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

使用aws4签名请求时排除负载签名失败问题排查

IAM保护的API Gateway Signature V4签名问题

我有一个受AWS IAM保护的API Gateway后端Lambda,希望通过Signature V4生成有效期5分钟的访问凭证,期间每次调用可传入不同负载。我使用aws4按如下方式签名请求:

const opts = {
  method: 'POST',
  host: '<myhostname>',
  path: '/path/to/resource',
  service: 'execute-api',
  region: 'my-region',
  headers: {
    'x-amz-content-sha256': 'UNSIGNED-PAYLOAD',
  },
};
const res = sign(opts);

我添加了x-amz-content-sha256头并设置值为UNSIGNED-PAYLOAD,告知AWS不要对负载签名(符合AWS文档说明),但调用端点时一直收到The String-to-Sign should have been错误。而如果设置固定负载(如下代码),签名则完全正常:

const opts = {
  method: 'POST',
  host: '<myhostname>',
  path: '/path/to/resource',
  service: 'execute-api',
  region: 'my-region',
  body: '{"value": "dummyPayload"}',
  headers: {
    'Content-Type': 'application/json',
  },
};
const res = sign(opts);

请问我在认证过程中遗漏了什么?


问题原因及解决方法

核心问题

  • 缺少Content-Type请求头:API Gateway在验证Signature V4时,即使使用UNSIGNED-PAYLOAD,也要求请求必须携带明确的Content-Type头。固定负载的代码中包含了该头,所以签名验证通过;而无负载的请求缺少该头,导致AWS生成的待签字符串和你本地生成的不一致,触发报错。
  • aws4库的处理逻辑:当未提供body参数时,aws4可能不会正确构建完整的待签字符串结构,即使你指定了x-amz-content-sha256头,也会导致签名不匹配。

修正方案

修改签名配置,补充Content-Type头,并添加对应格式的空请求体(即使不需要实际负载):

const opts = {
  method: 'POST',
  host: '<myhostname>',
  path: '/path/to/resource',
  service: 'execute-api',
  region: 'my-region',
  body: '{}', // 对应application/json格式的空内容,也可以用空字符串''
  headers: {
    'Content-Type': 'application/json',
    'x-amz-content-sha256': 'UNSIGNED-PAYLOAD',
  },
};
const res = sign(opts);

额外说明

  • 使用UNSIGNED-PAYLOAD时,AWS仅跳过请求体的哈希验证,但仍会校验请求方法、路径、请求头、时间戳等其他元数据的一致性。
  • 如果要复用签名(有效期5分钟),需确保每次调用时除了负载变化外,其他签名时的参数(如Content-Type)保持一致;如果每次调用重新生成签名,则需保证每次的配置结构统一。

内容的提问来源于stack exchange,提问作者Amine Boubcher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:00:21