亚马逊销售合作伙伴 API 403 - 签名错误

时间:2021-05-27 16:07:15

标签: node.js amazon-web-services cryptojs selling-partner-api

我正在尝试向亚马逊销售合作伙伴 API (node.js/Lambda) 发出请求,但我目前总是收到 403 错误。我已将相同的凭据和访问令牌插入 Postman,请求工作正常。我相信我在计算请求的签名时一定有错误,但我看不出任何错误。

我正在计算签名如下:

function constructCanonicalRequest(accessToken, dateTime) {
    let canonical = [];
    canonical.push('GET');
    canonical.push('/fba/outbound/2020-07-01/fulfillmentOrders/FBATestOrder-1');
    canonical.push('');
    canonical.push('host:' + 'sandbox.sellingpartnerapi-na.amazon.com');
    canonical.push('x-amz-access-token:' + accessToken);
    canonical.push('x-amz-date:' + dateTime);
    canonical.push('');
    canonical.push('host;x-amz-access-token;x-amz-date');
    canonical.push(crypto.SHA256(''));

    let canonicalRequest = canonical.join('\n');
    let canonicalRequestHash = crypto.SHA256(canonicalRequest);

    return canonicalRequestHash
};

function constructStringToSign(dateTime, date, canonicalRequestHash) {
    let stringToSign = [];
    stringToSign.push('AWS4-HMAC-SHA256')
    stringToSign.push(dateTime);
    stringToSign.push(date + '/' + 'us-east-1' + '/' + 'execute-api' + '/aws4_request');
    stringToSign.push(canonicalRequestHash);
    
    return stringToSign.join('\n');
};

function constructSignature(date, iamSecret, stringToSign) {
    let kDate = crypto.HmacSHA256(date, 'AWS4' + iamSecret);
    let kRegion = crypto.HmacSHA256('us-east-1', kDate);
    let kService = crypto.HmacSHA256('execute-api', kRegion);
    let kSigning = crypto.HmacSHA256('aws4_request', kService);

    let signature = crypto.HmacSHA256(stringToSign, kSigning).toString(crypto.enc.Hex);

    return signature
};

剩下的功能是:

        let dateTimeISO = new Date().toISOString();
        let dateTime = dateTimeISO.replace(/(\.\d{3})|\W/g,'');
        let date = dateTime.split('T')[0];

        let canonicalRequestHash = constructCanonicalRequest(accessToken, dateTimeISO);
        let stringToSign = constructStringToSign(dateTime, date, canonicalRequestHash);
        let signature = constructSignature(date, iamSecret, stringToSign);

        let authHeader = 'AWS4-HMAC-SHA256 Credential=' + iamId + '/' + date + '/' + 'us-east-1' + '/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date, Signature=' + signature

        console.log(authHeader);

        let amazonUrl = "https://sandbox.sellingpartnerapi-na.amazon.com/fba/outbound/2020-07-01/fulfillmentOrders/FBATestOrder-1";
        const amazonResponse = await fetch(amazonUrl, {
            method: 'get',
            headers: {
                'Authorization':authHeader,
                'Content-Type':'application/json; charset=utf-8',
                'host':'sandbox.sellingpartnerapi-na.amazon.com',
                'x-amz-access-token':accessToken,
                'user-agent': 'My Selling Tool/2.0 (Language=JS;Platform=Node)',
                'x-amz-date':dateTime,                
            }
        });

我还尝试使用多个不同的加密库来查看 HMAC 创建是否有问题,但这并没有解决任何问题。

1 个答案:

答案 0 :(得分:0)

我可以使用 C# 工作。 GitHub 上有一个 Java 库: https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md 我只是按照那里的说明进行操作,尽管 C# 库中存在关于承担角色的缺陷,即在 java 库中。