计算 Amazon Marketplace 提要的 MD5 散列问题
Issue calculating MD5 hash of Amazon Marketplace feed
我正在尝试向亚马逊商城提交 SubmitFeed
请求,但是当我提交请求时出现以下错误:
the Content-MD5 HTTP header you passed for your feed did not match the Content-MD5 we calculated for your feed
所以我在 Amazon Marketplace Scratchpad 上测试了请求。我将我的 XML 添加到 body 和 headers,它生成以下 MD5 哈希:
1db3b177e743dc8c0df4dc9eb5c1cbcf
但是还有一个Content-MD5 (Base64)
header,这个值为:
HbOxd+dD3IwN9NyetcHLzw==
似乎 实际发送到亚马逊的价值
MWS 作为 Content-MD5
HTTP header,而不是原始 MD5 哈希。
我检查了我的 PHP 脚本,它正确地生成了原始 MD5 散列,就像我将 XML 字符串包装在 md5
函数中一样(md5($xml)
) 我得到了与亚马逊生成的相同的原始 MD5 散列。但是,如果我随后将 that 包装在 base64_encode
函数中,我会得到一个完全不同的值,即亚马逊列出的 Content-MD5 (Base64) 值。
到目前为止,我已尝试将以下内容包装在 base64_encode
函数中:
- 原始XML字符串
- 原始 XML 字符串的 MD5 哈希值
但是 none 产生与亚马逊的 Content-MD5 (Base64) 值相同的值。
那么 究竟是什么 Amazon Base64 编码来获取该值?我已经尝试解码该值,但只是收到了一堆似乎是编码问题的随机字符,所以我看不到亚马逊编码的原始字符串,无法为我指明正确的方向。
如有任何相关指导,我们将不胜感激。
找到解决方案。我决定查看 md5
函数的文档,发现还有第二个参数来获取函数的 原始输出 ,默认情况下为 false
.因此,我决定将该标志设置为 true
,并对 that 调用的结果进行 Base64 编码。
瞧!我得到了与亚马逊相同的 Base64 值!
使用 Guzzle,这就是我发送到亚马逊的内容,现在我收到了成功的回复:
$xml = trim($xml);
// For some reason, the time my PHP script is sending is about 20 minutes out
// from my system time. This fixes that.
$timestamp = gmdate('c', time() + 1200);
$url = 'https://mws.amazonservices.co.uk/';
$parameters = [
'Action' => 'SubmitFeed',
'AWSAccessKeyId' => '#MY_ACCESS_KEY_ID#',
'FeedType' => '_POST_PRODUCT_DATA_',
'MarketplaceIdList.Id.1' => 'A1F83G8C2ARO7P', # UK marketplace ID
'Merchant' => '#MY_SELLER_ID#',
'PurgeAndReplace' => 'false',
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'Timestamp' => $timestamp,
'Version' => '2009-01-01',
];
/**
* Custom class that generates signature for request.
*
* @see
*/
$signature = new Signature($url, $parameters, '#MY_SECRET_ACCESS_KEY#');
$parameters['Signature'] = (string) $signature;
try {
$response = $this->client->post($url, [
'headers' => [
'Content-MD5' => base64_encode(md5($xml, true)),
'User-Agent' => '#MY_USER_AGENT_STRING#',
],
'query' => $parameters,
'body' => $xml,
]);
} catch (\GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
}
return $response->xml();
希望这对其他人有帮助!
我正在尝试向亚马逊商城提交 SubmitFeed
请求,但是当我提交请求时出现以下错误:
the Content-MD5 HTTP header you passed for your feed did not match the Content-MD5 we calculated for your feed
所以我在 Amazon Marketplace Scratchpad 上测试了请求。我将我的 XML 添加到 body 和 headers,它生成以下 MD5 哈希:
1db3b177e743dc8c0df4dc9eb5c1cbcf
但是还有一个Content-MD5 (Base64)
header,这个值为:
HbOxd+dD3IwN9NyetcHLzw==
似乎 实际发送到亚马逊的价值
MWS 作为 Content-MD5
HTTP header,而不是原始 MD5 哈希。
我检查了我的 PHP 脚本,它正确地生成了原始 MD5 散列,就像我将 XML 字符串包装在 md5
函数中一样(md5($xml)
) 我得到了与亚马逊生成的相同的原始 MD5 散列。但是,如果我随后将 that 包装在 base64_encode
函数中,我会得到一个完全不同的值,即亚马逊列出的 Content-MD5 (Base64) 值。
到目前为止,我已尝试将以下内容包装在 base64_encode
函数中:
- 原始XML字符串
- 原始 XML 字符串的 MD5 哈希值
但是 none 产生与亚马逊的 Content-MD5 (Base64) 值相同的值。
那么 究竟是什么 Amazon Base64 编码来获取该值?我已经尝试解码该值,但只是收到了一堆似乎是编码问题的随机字符,所以我看不到亚马逊编码的原始字符串,无法为我指明正确的方向。
如有任何相关指导,我们将不胜感激。
找到解决方案。我决定查看 md5
函数的文档,发现还有第二个参数来获取函数的 原始输出 ,默认情况下为 false
.因此,我决定将该标志设置为 true
,并对 that 调用的结果进行 Base64 编码。
瞧!我得到了与亚马逊相同的 Base64 值!
使用 Guzzle,这就是我发送到亚马逊的内容,现在我收到了成功的回复:
$xml = trim($xml);
// For some reason, the time my PHP script is sending is about 20 minutes out
// from my system time. This fixes that.
$timestamp = gmdate('c', time() + 1200);
$url = 'https://mws.amazonservices.co.uk/';
$parameters = [
'Action' => 'SubmitFeed',
'AWSAccessKeyId' => '#MY_ACCESS_KEY_ID#',
'FeedType' => '_POST_PRODUCT_DATA_',
'MarketplaceIdList.Id.1' => 'A1F83G8C2ARO7P', # UK marketplace ID
'Merchant' => '#MY_SELLER_ID#',
'PurgeAndReplace' => 'false',
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'Timestamp' => $timestamp,
'Version' => '2009-01-01',
];
/**
* Custom class that generates signature for request.
*
* @see
*/
$signature = new Signature($url, $parameters, '#MY_SECRET_ACCESS_KEY#');
$parameters['Signature'] = (string) $signature;
try {
$response = $this->client->post($url, [
'headers' => [
'Content-MD5' => base64_encode(md5($xml, true)),
'User-Agent' => '#MY_USER_AGENT_STRING#',
],
'query' => $parameters,
'body' => $xml,
]);
} catch (\GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
}
return $response->xml();
希望这对其他人有帮助!