我正在尝试使用 AWS S3 服务以 Swift 语言托管我的 iOS 应用程序的图像。 在此步骤中,我只是尝试使用 POST 请求简单地发布 png 图像。 在 AWS S3 的任何 POST 请求中,我们需要创建一个授权 header ,其中包含验证此请求的信息。为了使用 Amazon 所需的 HMAC SHA256 对数据进行编码,我使用 GitHub 项目作为我的子项目,链接如下:https://github.com/krzyzanowskim/CryptoSwift 这帮助我加密了签名,但是当我尝试发送此请求时,我收到一条错误,其中显示:“SignatureDoesNotMatch我们计算的请求签名与您提供的签名不匹配。请检查您的 key 和签名方法。”
这是我的代码:
var img = UIImage(named: "myImage.png")
var imageData : NSData = UIImageJPEGRepresentation(img, 1.0)
let key = "mybucketname"
let url = NSURL(string:"http://mybucket.s3.amazonaws.com/")
var request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
let uniqueId = NSProcessInfo.processInfo().globallyUniqueString
var postBody:NSMutableData = NSMutableData()
var boundary:String = "------WebKitFormBoundary\(uniqueId)"
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField:"Content-Type")
// I am trying to generate a date stamp compatible for request
let date = NSDate()
let formatter = NSDateFormatter()
formatter.timeStyle = .ShortStyle
formatter.stringFromDate(date)
var dateKey = ["AWS4"+"My AWSSecretKey","20150317"]
// Here is the signature that I'm trying to make
var signature = "My AWSSecretKey".sha256()?.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
request.addValue("AWS MYAWSACCESSKEYID:\(signature)", forHTTPHeaderField: "Authorization")
request.addValue("Wed, 18 Mar 2015 20:39:27 +0000", forHTTPHeaderField: "Date")
request.addValue(key, forHTTPHeaderField:"key")
request.addValue("\(postBody.length)", forHTTPHeaderField:"Content-Length")
postBody.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
postBody.appendData("Content-Type: image/png\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
postBody.appendData(imageData)
var postData = String()
postData += "\r\n"
postData += "\r\n--\(boundary)--\r\n"
postBody.appendData(postData.dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = postBody
var error: NSError?
let session = NSURLSession.sharedSession()
var task = session.dataTaskWithRequest(request, completionHandler: { (data, response, err) -> Void in
var stringData = NSString(data: data, encoding: NSUTF8StringEncoding)
var conversionError: NSError?
var jsonDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableLeaves, error: &conversionError) as? NSDictionary
})
task.resume()
我需要找出如何制作正确的签名以及如何对其进行加密,因为这是我使用此类工具的时间。
最佳答案
您不应该在您的应用程序中硬编码 key - 这会破坏其安全性。我建议从您自己的服务器生成 key (例如使用优秀的 S3Direct django 模块),然后像这样获取 key :
let filename = "myfile.mp4"
let requestUrl = Constants.my_own_server+"/s3direct/get_upload_params/"
println("Uploading file of name ***" + filename + "***")
let defaults = NSUserDefaults.standardUserDefaults()
let authToken : String = defaults.stringForKey("token")!
let manager = Manager.sharedInstance
manager.session.configuration.HTTPAdditionalHeaders = [
"Authorization": "Token " + authToken
]
let parameters : [ String : AnyObject] = [
"type": "video/mp4",
"name": filename,
"dest": "vids"
]
Alamofire.request(.POST, requestUrl, parameters: parameters).response(serializer: Request.JSONResponseSerializer(), completionHandler: { (request, response, object, error) -> Void in
//println(object)
//println(error)
if (error == nil) {
self.uploadFile(videoData!, parameters: object as! [ String : String], filename: filename)
}
else {
print("Failed to sign file")
}
})
祝你好运 - 我发现这个特定的堆栈工作起来异常痛苦。
关于xcode - 在 Swift 中发出 Amazon Web Services S3 POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29135487/