Amazon SP-API 对接指南:解决 SignatureDoesNotMatch 错误
2024-10-27 21:29:21
在对接 Amazon SP-API 的过程中,SignatureDoesNotMatch
错误就像一块绊脚石,时常让开发者感到头疼。这个错误提示的核心意思是,你计算的请求签名与 Amazon 计算的签名不一致。这就好比两把钥匙,虽然看起来很像,但齿形却存在细微差异,导致无法打开同一扇门。引发这种差异的原因,往往是签名过程中的一些细节处理不到位。你提到已经尝试了 httpPutRequest
和 GuzzleHttp\Client
、JSON 和 XML 格式,以及不同的请求头等多种方法,但问题依然存在,这说明问题可能隐藏在更深层次。
我们先来回顾一下 Amazon SP-API 签名机制的核心流程。它可以概括为以下四个步骤:
- 构建规范请求 (Canonical Request) : 将 HTTP 请求的各个部分(方法、路径、查询参数、请求头、请求体等)按照特定的规则组合成一个字符串。
- 生成签名密钥 (Signing Key) : 使用你的 AWS 访问密钥 ID 和密钥,结合日期、区域和服务名称等信息,生成一个用于签名的密钥。
- 构建字符串待签名 (String to Sign) : 将签名算法、日期、区域、服务名称以及规范请求的哈希值等信息组合成一个字符串。
- 生成签名 (Signature) : 使用签名密钥对字符串待签名进行哈希运算,得到最终的签名。
根据你提供的代码片段以及你的尝试,我推测导致 SignatureDoesNotMatch
错误的原因可能出现在以下几个方面:
1. 规范请求的构建
规范请求的构建是签名过程的第一步,也是非常关键的一步。任何细微的错误都可能导致最终签名的不一致。以下是一些需要注意的细节:
- 请求路径 : 确保
$path
变量中存储的请求路径是准确无误的,包括任何查询参数。如果你的请求路径包含查询参数,需要将它们按照字母顺序排序,并使用 URL 编码进行编码,然后再添加到$path
变量中。 - 请求头 : 请求头也需要按照字母顺序排序。每个请求头的名称需要转换为小写,并且名称和值之间需要用冒号分隔,例如
host:sellingpartnerapi-na.amazon.com
。此外,你需要确保请求头中包含了所有必需的头,例如Content-Type
、Content-MD5
、x-amz-date
等。 - 请求体 : 如果你的请求包含请求体,需要确保
$post
变量中存储的是正确的请求体内容。如果是 JSON 格式,需要确保 JSON 的格式正确,并且没有额外的空格或换行符。如果是 XML 格式,也需要确保 XML 的格式正确,并且没有额外的空格或换行符。
2. 签名密钥的生成
签名密钥的生成依赖于你的 AWS 访问密钥 ID 和密钥,以及日期、区域和服务名称等信息。请仔细检查以下几点:
- AWS 访问密钥 ID 和密钥 : 确保
IAM_USER_KEY
和IAM_USER_SECRET
变量中存储的是正确的 AWS 访问密钥 ID 和密钥。 - 日期和区域 : 确保
$ymd
和REGION
变量中存储的是正确的日期和区域信息。日期格式必须为YYYYMMDD
,例如20231026
。区域信息必须与你的 Amazon SP-API 账户所在的区域一致,例如us-east-1
。 - 服务名称 : 确保你在生成签名密钥时使用了正确的服务名称,例如
execute-api
。
3. 字符串待签名的构建
字符串待签名是根据签名算法、日期、区域、服务名称以及规范请求的哈希值构建的。请确保以下几点:
- 签名算法 : Amazon SP-API 使用
AWS4-HMAC-SHA256
签名算法。 - 日期、区域和服务名称 : 确保
$date
、$ymd
、REGION
和服务名称的值与你在生成签名密钥时使用的一致。 - 规范请求的哈希值 : 确保你使用 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-Type
、Content-MD5
、x-amz-date
等。缺少这些头会导致签名验证失败。
3. 为什么我的日期格式不正确会导致签名失败?
答:Amazon SP-API 要求日期格式必须为 YYYYMMDD
,例如 20231026
。如果你的日期格式不正确,会导致签名验证失败。
4. 为什么我的区域信息不正确会导致签名失败?
答:你的区域信息必须与你的 Amazon SP-API 账户所在的区域一致,例如 us-east-1
。如果你的区域信息不正确,会导致签名验证失败。
5. 为什么我的签名密钥不正确会导致签名失败?
答:签名密钥是根据你的 AWS 访问密钥 ID 和密钥,结合日期、区域和服务名称等信息生成的。如果你的 AWS 访问密钥 ID 或密钥不正确,或者日期、区域或服务名称不正确,都会导致签名密钥不正确,从而导致签名验证失败。
希望以上分析和建议能够帮助你解决 SignatureDoesNotMatch
错误,祝你顺利对接 Amazon SP-API!