【问题标题】:Issue calculating MD5 hash of Amazon Marketplace feed计算 Amazon Marketplace 提要的 MD5 哈希的问题
【发布时间】:2015-07-01 10:27:59
【问题描述】:

我正在尝试向亚马逊商城提交 SubmitFeed 请求,但在提交请求时出现以下错误:

您为供稿传递的 Content-MD5 HTTP 标头与我们为您的供稿计算的 Content-MD5 不匹配

所以我在Amazon Marketplace Scratchpad 上测试了请求。我将我的 XML 添加到正文和标题中,它会生成以下 MD5 哈希:

1db3b177e743dc8c0df4dc9eb5c1cbcf

但也有一个Content-MD5 (Base64) 标头,具有这个值:

HbOxd+dD3IwN9NyetcHLzw==

实际上发送到亚马逊的似乎是 那个值 MWS 作为Content-MD5 HTTP 标头,而不是原始 MD5 哈希。

我检查了我的 PHP 脚本,它正确地生成了原始 MD5 哈希,当我将我的 XML 字符串包装在 md5 函数 (md5($xml)) 中时,我得到了与亚马逊生成的相同的原始 MD5 哈希。但是,如果我随后将 that 包装在 base64_encode 函数中,我会得到与 Amazon 为 Content-MD5 (Base64) 值列出的内容完全不同的值。

到目前为止,我已经尝试将以下内容包装在 base64_encode 函数中:

  • 原始 XML 字符串
  • 原始 XML 字符串的 MD5 哈希

但没有一个产生与亚马逊的 Content-MD5 (Base64) 值相同的值。

那么 Amazon Base64 编码究竟是什么来获得该值?我已经尝试解码该值,但只是加载了似乎是编码问题的随机字符,所以我看不到亚马逊编码的原始字符串来为我指明正确的方向。

我们将不胜感激。

【问题讨论】:

    标签: php base64 md5 amazon-mws amazon-marketplace


    【解决方案1】:

    找到了解决方案。我决定查看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 http://stackoverflow.com/a/29724063/102205
     */
    $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();
    

    希望这对其他人有帮助!

    【讨论】:

    • 谢谢!虽然我使用的是 java,但您关于在原始数据上执行 base64 而非 md5 字符串的信息非常有用,也解决了我的问题。
    • 嗨 Martin Bean,我也面临同样的问题,但我使用的是 node.js 的请求模块,我使用的是 Meteor (Javascript)。我已经通过了 base64 编码的 md5content 但得到了同样的错误。即使我没有在 FeddContent 中发送文件,它也给了我同样的错误。请帮助我解决这个问题,我将对此表示感谢。它需要 3 天,但我还没有找到任何解决方案。我提出的问题的链接是:- stackoverflow.com/questions/40180070/…
    猜你喜欢
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 2011-12-08
    • 2015-06-23
    • 1970-01-01
    • 2011-08-27
    • 2015-12-18
    • 2017-01-27
    相关资源
    最近更新 更多