从斯威夫特访问的Azure存储表 [英] Accessing Azure Table Storage from Swift

查看:203
本文介绍了从斯威夫特访问的Azure存储表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要访问从斯威夫特蔚蓝的表存储。
制作标题中的指令是这里
不过,我已经试图建立请求,但不能让它工作:

 让urlString =htt​​ps://开头<我的帐户> .table.core.windows.net / MyTable的
    让storageUrl = NSURL(字符串:urlString)
    让请求= NSMutableURLRequest(网址:storageUrl!)    //制作日期
    让我们的currentdate = NSDate的()
    让httpFormatter = NSDateFormatter()
    httpFormatter.timeZone = NSTimeZone(简称:GMT)
    httpFormatter.dateFormat =EEE,DD MMM YYYY HH':​​'毫米':'SS Z
    让httpTime = httpFormatter.stringFromDate(的currentdate)
    打印(httpTime)    让signingString =GET \\ n \\ n \\ n \\(httpTime)\\ N /<我的帐户> / MyTable的
    打印(signingString)
    KeyString中让= LT; myKeyString>
    让KEYDATA = keyString.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion:假的)!
    让signingData = signingString.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion:假的)!
    让长度:INT = INT(CC_SHA256_DIGEST_LENGTH)
    让hashResult = UnsafeMutablePointer< CUnsignedChar> .alloc(长)
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256),keyData.bytes,INT(keyData.length),signingData.bytes,INT(signingData.length),hashResult)
    打印(hashResult)
    让哈希= NSData的(字节数:hashResult,长度:INT(CC_SHA256_DIGEST_LENGTH))
    让hashString = hash.base64En codedStringWithOptions(NSDataBase64EncodingOptions([]))
    hashResult.destroy()
    //打印(hashString)    request.setValue(SharedKeyLite<我的帐户>:\\(hashString),forHTTPHeaderField:授权)
    request.setValue(0,forHTTPHeaderField:内容长度)
    request.setValue(应用/ JSON,forHTTPHeaderField:内容类型)
    request.setValue(httpTime,forHTTPHeaderField:X-MS-DATE)
    request.setValue(,forHTTPHeaderField:日期)
    request.HTTPMethod =GET    。NSURLSession.sharedSession()dataTaskWithRequest(请求,completionHandler:{(数据,回应,误差)
        如果让数据= {数据
            让datastring =的NSString(数据:数据,编码:NSUTF8StringEncoding)
            打印(datastring!)            //打印(响应)        }其他{            打印(错误)        }
    })。简历()

下面的正确答案之后,我做了一个扩展字符串,所以HMAC签署,是很容易做到的:

  //
// CryptoExtensions.swift
// LaochTestProject
//
//创建者拉尔斯·克里斯托弗森在16年2月1日。
//版权所有©2016年克里斯托弗拉尔斯。版权所有。
//进口基金会
    枚举CryptoAlgorithm {
        案例MD5,SHA1,SHA224,SHA256,SHA384,SHA512        VAR HMACAlgorithm:CCHmacAlgorithm {
            VAR结果:= 0
            切换自{
            案例.MD5:结果= kCCHmacAlgMD5
            案例.SHA1:结果= kCCHmacAlgSHA1
            案例.SHA224:结果= kCCHmacAlgSHA224
            案例.SHA256:结果= kCCHmacAlgSHA256
            案例.SHA384:结果= kCCHmacAlgSHA384
            案例.SHA512:结果= kCCHmacAlgSHA512
            }
            返回CCHmacAlgorithm(结果)
        }        VAR digestLength:诠释{
            VAR结果:的Int32 = 0
            切换自{
            案例.MD5:结果= CC_MD5_DIGEST_LENGTH
            案例.SHA1:结果= CC_SHA1_DIGEST_LENGTH
            案例.SHA224:结果= CC_SHA224_DIGEST_LENGTH
            案例.SHA256:结果= CC_SHA256_DIGEST_LENGTH
            案例.SHA384:结果= CC_SHA384_DIGEST_LENGTH
            案例.SHA512:结果= CC_SHA512_DIGEST_LENGTH
            }
            返回INT(结果)
        }
    }    扩展字符串{        FUNC HMAC(算法:CryptoAlgorithm,键:字符串) - GT;字符串{
            让strData是= self.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion:假的)!
            让KEYDATA =的NSData(base64En codedString:键,选择:NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
            让digestLen = algorithm.digestLength
            让hashResult = UnsafeMutablePointer< CUnsignedChar> .alloc(digestLen)
            CCHmac(algorithm.HMACAlgorithm,keyData.bytes,INT(keyData.length),strData.bytes,INT(strData.length),hashResult)
            让哈希= NSData的(字节数:hashResult,长度:digestLen)
            让hashString = hash.base64En codedStringWithOptions(NSDataBase64EncodingOptions([]))
            hashResult.destroy()
            返回hashString
        }
    }


解决方案

终于得到它的工作:)

下面是我的code列出在Azure存储帐户中的所有表:

  //
// main.swift
// Azure存储REST助手
//
//创建者拉夫Mantri于16年1月2日。
//进口基金会
让帐户名={帐户名称}
让urlString =htt​​ps://开头{帐户名称} .table.core.windows.net /表
让storageUrl = NSURL(字符串:urlString)
让请求= NSMutableURLRequest(网址:storageUrl!)
让我们的currentdate = NSDate的()
让httpFormatter = NSDateFormatter()
httpFormatter.timeZone = NSTimeZone(简称:GMT)
httpFormatter.dateFormat =EEE,DD MMM YYYY HH':​​'毫米':'SS Z
让httpTime = httpFormatter.stringFromDate(的currentdate)
打印(httpTime)让signingString =GET \\ n \\ n \\ n \\(httpTime)\\ N / {帐户名称} /表
打印(signingString)
KeyString中让={帐户关键}
让KEYDATA =的NSData(base64En codedString:KeyString中,选择:NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!让signingData = signingString.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion:假的)!
让长度:INT = INT(CC_SHA256_DIGEST_LENGTH)
让hashResult = UnsafeMutablePointer< CUnsignedChar> .alloc(长)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256),keyData.bytes,INT(keyData.length),signingData.bytes,INT(signingData.length),hashResult)
打印(hashResult)
让哈希= NSData的(字节数:hashResult,长度:INT(CC_SHA256_DIGEST_LENGTH))
让hashString = hash.base64En codedStringWithOptions(NSDataBase64EncodingOptions([]))
hashResult.destroy()打印(hashString)request.setValue(SharedKey {帐户名称}:\\(hashString),forHTTPHeaderField:授权)
request.setValue(0,forHTTPHeaderField:内容长度)request.setValue(httpTime,forHTTPHeaderField:X-MS-DATE)
request.setValue(,forHTTPHeaderField:日期)request.HTTPMethod =GET
打印(来到这里)
。NSURLSession.sharedSession()dataTaskWithRequest(请求,completionHandler:{(数据,回应,误差)
    如果让数据= {数据
        让datastring =的NSString(数据:数据,编码:NSUTF8StringEncoding)
        打印(datastring!)
        打印(说到这儿1)
        //打印(响应)    }其他{
        打印(来到这里2)
        打印(错误)    }
})。简历()

几件事情,我所做的:


  • 而不是使用UTF8编码来获得 KEYDATA ,我创建的的NSData 使用 base64Encoding

  • 我摆脱内容类型头这样的结果以XML返回。如果你想以JSON格式返回数据,请指定接受头,而不是内容类型头。

  • 您正在使用但你在授权<指定的 SharedKeyLite SharedKey 方案创建签名/ code>头。我改变了以 SharedKey

哦,请不要判断code和随意编辑。我知道这是不是最好的code:)

I want to access the azure table storage from Swift. The instruction for making the header is here However, I have tried to build the request but can't make it work:

 let urlString =   "https://<myaccount>.table.core.windows.net/MyTable"
    let storageUrl = NSURL( string: urlString)
    let request = NSMutableURLRequest(URL: storageUrl!)

    //making the date
    let currentDate = NSDate()
    let httpFormatter = NSDateFormatter()
    httpFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
    httpFormatter.dateFormat = "EEE',' dd MMM yyyy HH':'mm':'ss z"
    let httpTime = httpFormatter.stringFromDate(currentDate)
    print(httpTime)

    let signingString = "GET\n\n\n\(httpTime)\n/<myaccount>/MyTable"
    print(signingString)


    let keyString = <myKeyString>
    let keyData = keyString.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion: false)!
    let signingData = signingString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    let length:Int = Int(CC_SHA256_DIGEST_LENGTH)
    let hashResult = UnsafeMutablePointer<CUnsignedChar>.alloc(length)
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyData.bytes, Int(keyData.length), signingData.bytes, Int(signingData.length), hashResult)
    print(hashResult)
    let hash = NSData(bytes: hashResult, length: Int(CC_SHA256_DIGEST_LENGTH))
    let hashString = hash.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
    hashResult.destroy()
    //print(hashString)

    request.setValue("SharedKeyLite <myaccount>:\(hashString)", forHTTPHeaderField: "Authorization")
    request.setValue("0", forHTTPHeaderField: "Content-Length")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue(httpTime, forHTTPHeaderField: "x-ms-date")
    request.setValue("", forHTTPHeaderField: "Date")
    request.HTTPMethod = "GET"

    NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in
        if let data = data {
            let datastring = NSString(data:data, encoding:NSUTF8StringEncoding)
            print( datastring! )

            //print(response)

        } else {

            print( error )

        }
    }).resume()

After the correct answer below, I made an extension to the String, so the hmac signing is very easy to do:

//
//  CryptoExtensions.swift
//  LaochTestProject
//
//  Created by Lars Christoffersen on 02/01/16.
//  Copyright © 2016 Lars Christoffersen. All rights reserved.
//

import Foundation


    enum CryptoAlgorithm {
        case MD5, SHA1, SHA224, SHA256, SHA384, SHA512

        var HMACAlgorithm: CCHmacAlgorithm {
            var result: Int = 0
            switch self {
            case .MD5:      result = kCCHmacAlgMD5
            case .SHA1:     result = kCCHmacAlgSHA1
            case .SHA224:   result = kCCHmacAlgSHA224
            case .SHA256:   result = kCCHmacAlgSHA256
            case .SHA384:   result = kCCHmacAlgSHA384
            case .SHA512:   result = kCCHmacAlgSHA512
            }
            return CCHmacAlgorithm(result)
        }

        var digestLength: Int {
            var result: Int32 = 0
            switch self {
            case .MD5:      result = CC_MD5_DIGEST_LENGTH
            case .SHA1:     result = CC_SHA1_DIGEST_LENGTH
            case .SHA224:   result = CC_SHA224_DIGEST_LENGTH
            case .SHA256:   result = CC_SHA256_DIGEST_LENGTH
            case .SHA384:   result = CC_SHA384_DIGEST_LENGTH
            case .SHA512:   result = CC_SHA512_DIGEST_LENGTH
            }
            return Int(result)
        }
    }

    extension String {

        func hmac(algorithm: CryptoAlgorithm, key: String) -> String {


            let strData = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
            let keyData = NSData(base64EncodedString: key, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
            let digestLen = algorithm.digestLength
            let hashResult = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
            CCHmac(algorithm.HMACAlgorithm, keyData.bytes, Int(keyData.length), strData.bytes, Int(strData.length), hashResult)
            let hash = NSData(bytes: hashResult, length: digestLen )
            let hashString = hash.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
            hashResult.destroy()
            return hashString
        }
    }

解决方案

Finally got it working :)

Here's my code which lists all tables in an Azure Storage account:

//
//  main.swift
//  Azure Storage REST Helper
//
//  Created by Gaurav Mantri on 1/2/16.
//

import Foundation
let accountName = "{account-name}"
let urlString = "https://{account-name}.table.core.windows.net/Tables"
let storageUrl = NSURL(string: urlString)
let request = NSMutableURLRequest(URL: storageUrl!)
let currentDate = NSDate()
let httpFormatter = NSDateFormatter()
httpFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
httpFormatter.dateFormat = "EEE',' dd MMM yyyy HH':'mm':'ss z"
let httpTime = httpFormatter.stringFromDate(currentDate)
print(httpTime)

let signingString = "GET\n\n\n\(httpTime)\n/{account-name}/Tables"
print(signingString)
let keyString = "{account-key}"
let keyData = NSData(base64EncodedString: keyString, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!

let signingData = signingString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let length:Int = Int(CC_SHA256_DIGEST_LENGTH)
let hashResult = UnsafeMutablePointer<CUnsignedChar>.alloc(length)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyData.bytes, Int(keyData.length), signingData.bytes, Int(signingData.length), hashResult)
print(hashResult)
let hash = NSData(bytes: hashResult, length: Int(CC_SHA256_DIGEST_LENGTH))
let hashString = hash.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
hashResult.destroy()

print(hashString)

request.setValue("SharedKey {account-name}:\(hashString)", forHTTPHeaderField: "Authorization")
request.setValue("0", forHTTPHeaderField: "Content-Length")

request.setValue(httpTime, forHTTPHeaderField: "x-ms-date")
request.setValue("", forHTTPHeaderField: "Date")

request.HTTPMethod = "GET"
print("comes here")
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in
    if let data = data {
        let datastring = NSString(data:data, encoding:NSUTF8StringEncoding)
        print( datastring! )
        print("comes here 1")
        //print(response)

    } else {
        print("comes here 2")
        print( error )

    }
}).resume()

A few things that I did:

  • Instead of using UTF8 encoding to get keyData, I created NSData using base64Encoding.
  • I got rid of Content-Type header so the result is returned in XML. If you want to return data in JSON format, please specify Accept header instead of Content-Type header.
  • You were creating signature using SharedKey scheme yet you specified SharedKeyLite in the Authorization header. I changed that to SharedKey.

Oh, and please don't judge the code and feel free to edit it. I know this is not the best code :)

这篇关于从斯威夫特访问的Azure存储表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆