亚马逊签名创作

时间:2016-07-26 18:10:25

标签: swift amazon-web-services

我正在尝试从亚马逊的API中实现我的应用内的itemLookup。我已经看过Swift的早期版本的文档,但它们似乎不再起作用了,但是我有一点工作。

我按照this post

中的说明从Javascript移植了代码

这是我到目前为止所做的:

PID

这是输出。

 func callAmazon(){

        let amazonAccessID = "XXXXXX"
        let secretKey = "XXXXXXXXX"
        let associateTag = "XXXXX"

        var parameters = [String]();

        let timestamp = ISO8601FormatStringFromDate(NSDate())

        parameters.append("AWSAccessKeyId=" + amazonAccessID);
        parameters.append("Keywords=" + "boots");
        parameters.append("Operation=ItemSearch");
        parameters.append("Service=AWSECommerceService");
        parameters.append("Timestamp=" + (timestamp as String));
        parameters.append("Version=2013-08-01");
        parameters.append("AssociateTag=" + associateTag);

        parameters.sortInPlace {$0 < $1}
        let paramString = parameters.joinWithSeparator("&")

        let method = NSMutableURLRequest().HTTPMethod

        let signingKey = "\(method)\n" + "webservices.amazon.com\n" + "/onca/xml\n" + paramString

        let signature = sha256(signingKey, secretKey: secretKey)

        let finalString = signature.encodeURIComponent()

        let amazonUrl =  "http://webservices.amazon.com/onca/xml?" + paramString + "&Signature=" + finalString!

        print("AmazonURL!!! : ", amazonUrl)


    Alamofire.request(.GET, amazonUrl, parameters: nil).response {
        (request, response, data, error) in
            let xml = SHXMLParser().parseData(data!)
            print(xml)// output the FilmID element.
    }


}

func sha256(StringToSign : String, secretKey : String) -> String{

    var hex = StringToSign.hmac(.SHA256, key: secretKey)
    let hexData = hex.dataUsingEncoding(NSUTF8StringEncoding)
    let finalString = hexData?.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)

    return finalString!

}

所以我创建签名的方式显然有问题,有人能指导我朝正确的方向发展吗?

2 个答案:

答案 0 :(得分:3)

亚马逊签名创建

以下是aws签名创建的解决方法。

这是swift中AWS签名创建问题的解决方案。 我创建了AWS请求参数。并用HMAC算法编码。

通过传递产品ID来调用callAmazon方法,作为响应,您将收到必须解析的xml响应。 试试这个例子: -

static func callAmazon(asinId: String){
    // provide your AmazonAccessID, SecretKey and AssociateTag
    let amazonAccessID = "xxxxxxx"
    let secretKey = "xxxxxxx"
    let associateTag = "xxxxx"

    var parameters = [String]();

    let timestamp = Date().iso8601.encodeURIComponent()!

    parameters.append("AWSAccessKeyId=" + amazonAccessID)
    parameters.append("Operation=ItemLookup")
    parameters.append("Service=AWSECommerceService")
    parameters.append("Timestamp=" + (timestamp as String))
    parameters.append("AssociateTag=" + associateTag)
    parameters.append("ResponseGroup="+"Offers")
    parameters.append("ItemId="+asinId)
    parameters.append("IdType=ASIN")

    parameters.sort {$0 < $1}
    let paramString = parameters.joined(separator: "&")

    let method = NSMutableURLRequest().httpMethod

    let signingKey = "\(method)\n" + "webservices.amazon.com\n" + "/onca/xml\n" + paramString

    let signature = signingKey.hmac(algorithm: .SHA256, key: secretKey)

    let finalString = signature.encodeURIComponent()

    let amazonUrl =  "http://webservices.amazon.com/onca/xml?" + paramString + "&Signature=" + finalString!

    print("AmazonURL!!! :", amazonUrl)


    AppNetworking.serviceRequestPrice(endPoint: amazonUrl, success: { (data) in

        if let data = data{

            print(String(data: data, encoding: .utf8) ?? "CANNOT CONVERT")
        }

    }) { (error) in
        print(error)
    }

    }

extension HMACAlgorithm{

func toCCHmacAlgorithm() -> 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)
}

func digest_Length() -> Int {

    var result: CInt = 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 {
// returning encoded signature
func hmac(algorithm: HMACAlgorithm, key: String) -> String {
    let cKey = key.cString(using: String.Encoding.utf8)
    let cData = self.cString(using: String.Encoding.utf8)
    var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digest_Length()))
    CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, Int(strlen(cKey!)), cData!, Int(strlen(cData!)), &result)
    let hmacData:NSData = NSData(bytes: result, length: (Int(algorithm.digestLength())))

    let hmacBase64 = hmacData.base64EncodedData(options: NSData.Base64EncodingOptions.lineLength64Characters)

   return String(data: hmacBase64, encoding:  String.Encoding.utf8)!
} }

extension String {
// returning encoded url string
func encodeURIComponent() -> String? {
    let characterSet = NSMutableCharacterSet.alphanumeric()
    characterSet.addCharacters(in: "-_.!~*'()")

    return self.addingPercentEncoding(withAllowedCharacters: characterSet as CharacterSet)
}}

extension Formatter {
// returning iso dateformater
static let iso8601: DateFormatter = {
    let formatter = DateFormatter()
    formatter.calendar = Calendar(identifier: .iso8601)
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
    //"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"//"yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
    return formatter
}() }

extension Date {
// returning iso date
var iso8601: String {
    return Formatter.iso8601.string(from: self)
}}

答案 1 :(得分:1)

我可以看到的一件事是,您的标题未以\n结束。