从斯威夫特访问的Azure存储表 [英] Accessing Azure Table Storage from Swift
本文介绍了从斯威夫特访问的Azure存储表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我要访问从斯威夫特蔚蓝的表存储。
制作标题中的指令是这里
不过,我已经试图建立请求,但不能让它工作:
让urlString =https://开头<我的帐户> .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 =https://开头{帐户名称} .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 code>使用
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 createdNSData
usingbase64Encoding
. - I got rid of
Content-Type
header so the result is returned in XML. If you want to return data in JSON format, please specifyAccept
header instead ofContent-Type
header. - You were creating signature using
SharedKey
scheme yet you specifiedSharedKeyLite
in theAuthorization
header. I changed that toSharedKey
.
Oh, and please don't judge the code and feel free to edit it. I know this is not the best code :)
这篇关于从斯威夫特访问的Azure存储表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文