परिदृश्य:स्विफ्ट अलामोफायर फ़ाइल हस्ताक्षरित अनुरोध के साथ अपलोड करें: प्राधिकरण शीर्षलेख कैसे भेजें?
- iPhone आईओएस 8 अनुप्रयोग
- प्रवेश प्रयोक्ता एप्लिकेशन पहले से ही Alamofire का उपयोग करता बैकएंड एपीआई के लिए अनुबंधित किया अनुरोध करने के लिए एक प्रोफ़ाइल तस्वीर
अपलोड कर देगा। वास्तव में सरल: ऐप हस्ताक्षरित होने के अनुरोध के लिए तीन विशिष्ट HTTP शीर्षलेख (Authorization
, X-Api-Key
और timestamp
) भेजता है। Alamofire.request
पर कॉल करना headers
पैरामीटर के रूप में भेजना आसान है, इसलिए यह खूबसूरती से काम कर रहा है।
अब उपयोगकर्ताओं को अपलोड करने की आवश्यकता है उनकी प्रोफ़ाइल तस्वीर। चूंकि उपयोगकर्ता पहले से ही ऐप में लॉग इन है, बैकएंड एपीआई यह जान लेगा कि कौन सा उपयोगकर्ता चित्र हस्ताक्षरित अनुरोध द्वारा चित्र भेज रहा है - और यह मुश्किल हिस्सा है जो मैं पिछले कुछ घंटों से संघर्ष कर रहा हूं। Alamofire.upload
.request
से पूरी तरह से अलग पैरामीटर स्वीकार करता है, इसलिए मैं फ़ाइल अपलोड करते समय हेडर भेजने का तरीका नहीं समझ सकता।
पुराने Alamofire.Manager.session.configuration.HTTPAdditionalHeaders
का प्रयास किया, लेकिन यह no longer supported है। फाइल अपलोड के टन कोड उदाहरण मिले, कोई भी कस्टम हेडर भेजने पर विचार नहीं करता है।
Alamofire.upload
विधि का उपयोग करते समय मैं कस्टम हेडर कैसे भेज सकता हूं?
typealias requestDataType = [String:AnyObject]
private func signRequest(data: requestDataType) -> [String:String] {
var headers = [String:String]()
var authString = ""
var signatureHeaders = ""
// Iterates over SORTED data dictionary to build headers
for (k,v) in (data.sort{$0.0 < $1.0}) {
if !authString.isEmpty {
authString += "\n"
signatureHeaders += " "
}
authString += "\(k): \(v)"
signatureHeaders += "\(k)"
headers[k] = "\(v)"
}
let userApiKey = _loggedInUser!["api_key"].string!
let signature = authString.sha256(_loggedInUser!["api_secret"].string!)
headers["X-Api-Key"] = userApiKey
headers["Authorization"] = "Signature headers=\"\(signatureHeaders)\",keyId=\"\(userApiKey)\",algorithm=\"hmac-sha256\",signature=\"\(signature)\""
return headers
}
func uploadProfilePicture(photo: UIImage, callback: apiCallback){
guard let userId = _loggedInUser?["pk"].int else {
callback(Response(success: false, responseMessage: "User not logged in"))
return
}
let requestData: requestDataType = ["timestamp": "\(Int(NSDate().timeIntervalSince1970))"]
let aManager = Manager.sharedInstance
print(self.signRequest(requestData)) // Prints correct headers (Authorization, X-Api-Key, timestamp)
aManager.session.configuration.HTTPAdditionalHeaders = self.signRequest(requestData)
print(aManager.session.configuration.HTTPAdditionalHeaders) // Prints default headers, completely ignoring my custom headers
aManager.upload(.POST, "\(_apiBaseUrl)profiles/\(userId)/photo/", multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(photo, 0.8) {
multipartFormData.appendBodyPart(data: imageData, name: "upload", fileName: "userphoto.jpg", mimeType: "image/jpeg")
}
for (key, value) in requestData {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
}, encodingCompletion: {
encodingResult in
debugPrint(encodingResult)
})
}
अनुरोधों के माध्यम से अनुरोध किया जाता है। बैकएंड लॉग में मैं अनुरोध देख सकता हूं कि HTTP 403
लौटाया गया अनुरोध - अधिकृत नहीं है क्योंकि अनुरोध पर हस्ताक्षर करना संभव नहीं था। अनुरोध हेडर प्रिंट करना, सर्वर द्वारा कोई कस्टम ऑथ हेडर प्राप्त नहीं हुए थे।
जोड़े कम से कम 'signRequest' विधि –
@DavidBerry के लिए प्रोटोटाइप अपडेट किया गया। – mathielo