返回

Amazon SP-API 对接指南:解决 SignatureDoesNotMatch 错误

php

在对接 Amazon SP-API 的过程中,SignatureDoesNotMatch 错误就像一块绊脚石,时常让开发者感到头疼。这个错误提示的核心意思是,你计算的请求签名与 Amazon 计算的签名不一致。这就好比两把钥匙,虽然看起来很像,但齿形却存在细微差异,导致无法打开同一扇门。引发这种差异的原因,往往是签名过程中的一些细节处理不到位。你提到已经尝试了 httpPutRequestGuzzleHttp\Client、JSON 和 XML 格式,以及不同的请求头等多种方法,但问题依然存在,这说明问题可能隐藏在更深层次。

我们先来回顾一下 Amazon SP-API 签名机制的核心流程。它可以概括为以下四个步骤:

  1. 构建规范请求 (Canonical Request) : 将 HTTP 请求的各个部分(方法、路径、查询参数、请求头、请求体等)按照特定的规则组合成一个字符串。
  2. 生成签名密钥 (Signing Key) : 使用你的 AWS 访问密钥 ID 和密钥,结合日期、区域和服务名称等信息,生成一个用于签名的密钥。
  3. 构建字符串待签名 (String to Sign) : 将签名算法、日期、区域、服务名称以及规范请求的哈希值等信息组合成一个字符串。
  4. 生成签名 (Signature) : 使用签名密钥对字符串待签名进行哈希运算,得到最终的签名。

根据你提供的代码片段以及你的尝试,我推测导致 SignatureDoesNotMatch 错误的原因可能出现在以下几个方面:

1. 规范请求的构建

规范请求的构建是签名过程的第一步,也是非常关键的一步。任何细微的错误都可能导致最终签名的不一致。以下是一些需要注意的细节:

  • 请求路径 : 确保 $path 变量中存储的请求路径是准确无误的,包括任何查询参数。如果你的请求路径包含查询参数,需要将它们按照字母顺序排序,并使用 URL 编码进行编码,然后再添加到 $path 变量中。
  • 请求头 : 请求头也需要按照字母顺序排序。每个请求头的名称需要转换为小写,并且名称和值之间需要用冒号分隔,例如 host:sellingpartnerapi-na.amazon.com。此外,你需要确保请求头中包含了所有必需的头,例如 Content-TypeContent-MD5x-amz-date 等。
  • 请求体 : 如果你的请求包含请求体,需要确保 $post 变量中存储的是正确的请求体内容。如果是 JSON 格式,需要确保 JSON 的格式正确,并且没有额外的空格或换行符。如果是 XML 格式,也需要确保 XML 的格式正确,并且没有额外的空格或换行符。

2. 签名密钥的生成

签名密钥的生成依赖于你的 AWS 访问密钥 ID 和密钥,以及日期、区域和服务名称等信息。请仔细检查以下几点:

  • AWS 访问密钥 ID 和密钥 : 确保 IAM_USER_KEYIAM_USER_SECRET 变量中存储的是正确的 AWS 访问密钥 ID 和密钥。
  • 日期和区域 : 确保 $ymdREGION 变量中存储的是正确的日期和区域信息。日期格式必须为 YYYYMMDD,例如 20231026。区域信息必须与你的 Amazon SP-API 账户所在的区域一致,例如 us-east-1
  • 服务名称 : 确保你在生成签名密钥时使用了正确的服务名称,例如 execute-api

3. 字符串待签名的构建

字符串待签名是根据签名算法、日期、区域、服务名称以及规范请求的哈希值构建的。请确保以下几点:

  • 签名算法 : Amazon SP-API 使用 AWS4-HMAC-SHA256 签名算法。
  • 日期、区域和服务名称 : 确保 $date$ymdREGION 和服务名称的值与你在生成签名密钥时使用的一致。
  • 规范请求的哈希值 : 确保你使用 SHA256 算法计算了规范请求的哈希值。

4. 签名的生成

签名是使用签名密钥对字符串待签名进行哈希运算得到的。请确保你使用的是 HMAC-SHA256 算法,并且签名密钥和字符串待签名都计算正确。

5. 授权头的构建

授权头是将签名信息添加到 HTTP 请求头中的一种方式。请确保以下几点:

  • 授权头格式 : 授权头的格式必须符合 Amazon SP-API 的要求,例如:
Authorization: AWS4-HMAC-SHA256 Credential=AKIAXXXXXX/20231026/us-east-1/execute-api/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • 已签名的请求头名称 : 确保 SignedHeaders 参数中列出了所有参与签名的请求头名称,并且名称之间用分号分隔。
  • 签名 : 确保 Signature 参数中存储的是你计算得到的签名值。

其他建议

  • 使用 Amazon 提供的 SDK : Amazon 为多种编程语言提供了 SP-API SDK,这些 SDK 可以简化 SP-API 的对接过程,并自动处理签名等细节。如果你还没有使用 SDK,建议你尝试使用它。
  • 参考 Amazon 的官方文档 : Amazon 的官方文档提供了详细的 SP-API 使用指南和示例代码,可以帮助你更好地理解 SP-API 的工作原理。
  • 使用调试工具 : 你可以使用一些调试工具,例如 Postman 或 Fiddler,来捕获你的 HTTP 请求和响应,并检查请求头和签名信息是否正确。

常见问题及其解答

1. 为什么我的请求路径包含查询参数时,签名会失败?

答:当请求路径包含查询参数时,你需要将查询参数按照字母顺序排序,并使用 URL 编码进行编码,然后再添加到请求路径中。

2. 为什么我的请求头中缺少某些必需的头会导致签名失败?

答:Amazon SP-API 要求在请求头中包含一些必需的头,例如 Content-TypeContent-MD5x-amz-date 等。缺少这些头会导致签名验证失败。

3. 为什么我的日期格式不正确会导致签名失败?

答:Amazon SP-API 要求日期格式必须为 YYYYMMDD,例如 20231026。如果你的日期格式不正确,会导致签名验证失败。

4. 为什么我的区域信息不正确会导致签名失败?

答:你的区域信息必须与你的 Amazon SP-API 账户所在的区域一致,例如 us-east-1。如果你的区域信息不正确,会导致签名验证失败。

5. 为什么我的签名密钥不正确会导致签名失败?

答:签名密钥是根据你的 AWS 访问密钥 ID 和密钥,结合日期、区域和服务名称等信息生成的。如果你的 AWS 访问密钥 ID 或密钥不正确,或者日期、区域或服务名称不正确,都会导致签名密钥不正确,从而导致签名验证失败。

希望以上分析和建议能够帮助你解决 SignatureDoesNotMatch 错误,祝你顺利对接 Amazon SP-API!