Amazon Selling Partner API Token API を呼び出して RDT トークンを取得しようとしています。Orders API への GET リクエストを成功させる作業中のプログラムがありますが、Orders API への REST リクエストにはヘッダーと URL パラメーターのみが含まれています。トークン API リクエストには、制限付きリソースのリストが保存される HTTP 本文も (追加で) 含まれます。
Amazonは次のように返信します
The request signature we calculated does not match the signature you provided.
Check your AWS Secret Access Key and signing method.
Consult the service documentation for details.
The Canonical String for this request should have been
'GET
/tokens/2021-03-01/restrictedDataToken
...
host;x-amz-access-token;x-amz-date\n
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
...
The String-to-Sign should have been
...
...
私のトークンAPIプログラムで。e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
私の問題の鍵です。これは、ヘッダー、URL パラメーター、および本文コンテンツの初期セットからのコンピューターであるハッシュ化されたペイロード (次のリンクの図を参照) です。私のプログラムによって計算されるハッシュ化されたペイロードは、Amazon が本文なしのリクエストに対して返し、受け入れるものと同じです。しかし、Amazon と私のプログラムの Hashed ペイロードは、本文のあるリクエストでは異なります。したがって、私のプログラムは Amazon とは異なる方法で本体を追加およびハッシュすると結論付けました。それが、Amazon がトークン API リクエストを受け入れない理由です。
AWS - 正規のリクエストとは実際には何ですか? Amazonサービスへの完全なリクエストがどのように計算されるか、素晴らしい図があります。
C# コードを使用して HTTP 本文を計算して追加しています。
Model.RestrictedResource restrictedResource = new Model.RestrictedResource(
Model.RestrictedResource.MethodEnum.GET,
"/orders/v0/orders",
new List<String> {"buyerInfo", "shippingAddress"});
List<Model.RestrictedResource> restrictedResources = new List<Model.RestrictedResource>();
restrictedResources.Add(restrictedResource);
Model.CreateRestrictedDataTokenRequest request = new Model.CreateRestrictedDataTokenRequest("", restrictedResources);
IRestRequest restRequest = new RestRequest(rdt_resource, Method.GET);
restRequest.AddParameter("MarketplaceIds", marketplace_id, ParameterType.QueryString);
restRequest.AddJsonBody(Serialize(request));
//restRequest.AddBody(Serialize(request)); //Alternative solution, the same Amazon error about differing hashed payload values
ハッシュ化された CanonicalRequest 文字列を計算するコードは次のとおりです。
public IRestRequest Sign(IRestRequest request, string host)
{
DateTime signingDate = AwsSignerHelper.InitializeHeaders(request, host);
string signedHeaders = AwsSignerHelper.ExtractSignedHeaders(request);
string hashedCanonicalRequest = CreateCanonicalRequest(request, signedHeaders);
string stringToSign = AwsSignerHelper.BuildStringToSign(signingDate,
hashedCanonicalRequest,
awsCredentials.Region);
string signature = AwsSignerHelper.CalculateSignature(stringToSign,
signingDate,
awsCredentials.SecretKey,
awsCredentials.Region);
AwsSignerHelper.AddSignature(request,
awsCredentials.AccessKeyId,
signedHeaders,
signature,
awsCredentials.Region,
signingDate);
return request;
}
private string CreateCanonicalRequest(IRestRequest restRequest, string signedHeaders)
{
var canonicalizedRequest = new StringBuilder();
//Request Method
canonicalizedRequest.AppendFormat("{0}\n", restRequest.Method);
//CanonicalURI
canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalURIParameters(restRequest.Resource));
//CanonicalQueryString
canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalQueryString(restRequest));
//CanonicalHeaders
canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalHeaders(restRequest));
//SignedHeaders
canonicalizedRequest.AppendFormat("{0}\n", signedHeaders);
// Hash(digest) the payload in the body
canonicalizedRequest.AppendFormat(AwsSignerHelper.HashRequestBody(restRequest));
string canonicalRequest = canonicalizedRequest.ToString();
//Create a digest(hash) of the canonical request
return Utils.ToHex(Utils.Hash(canonicalRequest));
}
//This seems to be the key code - how body is extracted and hashed
public virtual string HashRequestBody(IRestRequest request)
{
Parameter body = request.Parameters.FirstOrDefault(parameter => ParameterType.RequestBody.Equals(parameter.Type));
string value = body != null ? body.Value.ToString() : string.Empty;
return Utils.ToHex(Utils.Hash(value));
}
だから、私は行方不明で、どこかでAmazonの慣習に従っていませんが、どこで. 何かがうまくいかない可能性があるポイントは複数ありrestRequest.AddJsonBody(Serialize(request));
ます。2)HashRequestBody
別の方法で実装する必要があるかもしれません (インターネットのどこかでコードを見つけたか、販売パートナーの API 仕様から Swagger によって生成されたコードを見つけました。
コードを微調整して、同じリクエスト (つまり、計算に使用され、計算の前に正規化されるリクエストの一部) に対して Amazon によって計算されたものとまったく同じハッシュ化されたペイロード (本文を含むリクエストの場合) を生成する方法ハッシュ化されたペイロードの)。