You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails对接亚马逊SP API时SigV4签名不匹配报错如何解决?

我遇到的报错如下:

The request signature we calculated does not match the signature you provided
The Canonical String for this request should have been
The String-to-Sign should have been

我在Rails框架中对接亚马逊SP API的流程如下:

第一步:获取Access Token

payload = {
  grant_type: 'refresh_token',
  client_id: [ClientId],
  refresh_token: [RefreshToken],
  client_secret: [ClientSecret],
}
headers = {'Content-Type': 'application/json'}
response = HTTParty.post("https://api.amazon.com/auth/o2/token", body: payload.to_json, headers: headers)
access_token = response["access_token"]

第二步:调用AWS STS接口角色扮演获取临时凭证

sts = Aws::STS::Client.new(
  region: "us-east-1",
  credentials: Aws::Credentials.new("aws-access-key", "aws-secret-key")
)
result = sts.assume_role({
  role_arn: "role_arn",
  role_session_name: 'sp-api'
})

第三步:生成SigV4签名

signer = Aws::Sigv4::Signer.new(
  service: 'execute-api',
  region: 'us-east-1',
  access_key_id: access_key_id,
  secret_access_key: secret_access_key,
  session_token: session_token
)

signature = signer.sign_request(
  http_method: 'GET',
  url: 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID',
  headers: {
    'host' => 'sellingpartnerapi-na.amazon.com',
    'X-Amz-Access-Token' => access_token,
  })

第四步:携带签名调用SP API

headers = {
  'Content-Type' => 'application/json',
  "host" => signature.headers["host"],
  "X-Amz-Date" => signature.headers['x-amz-date'],
  "X-Amz-Security-Token" => signature.headers["x-amz-security-token"],
  "X-Amz-Content-Sha256" => signature.headers["x-amz-content-sha256"],
  "Authorization" => signature.headers['authorization']
}

data = HTTParty.send(:get, "https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID", headers: headers)

错误原因&修复方案

上述流程中存在4处可直接导致签名不匹配的问题,按优先级排查修复即可:

  • STS凭证取值错误:第二步返回的result对象才是临时凭证的载体,需要从result.credentials.access_key_id、result.credentials.secret_access_key、result.credentials.session_token三个字段取值传入第三步的签名器,不要误传入根账号的AK/SK。同时确认使用的role_arn已经完成SP API授权绑定,无权限会间接触发签名校验失败。
  • 签名头包含不需要校验的字段:X-Amz-Access-Token是SP API要求的请求头,但不属于SigV4签名的校验范围,第三步中将该字段传入sign_request的headers参数,会导致签名计算时纳入该字段,AWS校验时不校验该字段,最终签名不匹配。
  • 请求时缺失X-Amz-Access-Token头:第四步发起请求时没有携带X-Amz-Access-Token头,该头是SP API的必填字段,不需要参与签名,但请求时必须传入。
  • 多余请求头干扰校验:GET请求不需要携带Content-Type: application/json头,多余的头如果和签名时的头列表不一致也会触发校验失败。

代码修改参考

  1. 调整第三步签名代码,移除不需要参与签名的头:
signature = signer.sign_request(
  http_method: 'GET',
  url: 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID',
  headers: {
    'host' => 'sellingpartnerapi-na.amazon.com'
  })
  1. 调整第四步请求头,直接合并签名返回的所有头,补充必填的SP API专属头:
headers = signature.headers.merge({
  'X-Amz-Access-Token' => access_token
})
data = HTTParty.get("https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID", headers: headers)

通用排查方法

如果修改后仍报错,将自己生成签名时的Canonical String和报错提示的官方要求Canonical String逐字符对比,不一致的位置就是错误点,常见的差异包括路径大小写错误、query参数顺序错误、请求体哈希值不匹配。

内容的提问来源于stack exchange,提问作者Hunaid Nawaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 15:54:02