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

将AWS预签名URL转为Header授权请求(httr2报400错误)

问题分析与修复方案

你的请求构造存在三个核心错误,直接导致了400 Bad Request:


1. Authorization Header格式错误

SignedHeaders字段只能包含header名称(小写),不能附带任何值——你之前把x-amz-date=xxxx这种带值的写法放进去,完全不符合AWS的签名规范。同时要保证SignedHeaders里的header列表,和实际请求中发送的签名header完全一致,顺序也要对应。

2. Credential字符串未解码

原预签名URL里的%2F是斜杠/的URL编码,转成Header授权时必须解码成原始的/,不能保留编码后的%2F,否则AWS无法正确解析凭证信息。

3. 错误处理X-Amz-Expires

X-Amz-Expires是预签名URL的专属参数,不需要作为请求Header发送,也不能出现在SignedHeaders里——它的有效期已经包含在签名逻辑中,直接忽略这个参数即可。


正确的请求构造示例(httr2)

library(httr2)

# 从原始预签名URL提取的关键信息
bucket <- "<my-bucket>"
file_path <- "<path/to/file.dat>"
credential_string <- "<credential-string>"
amz_date <- "20241107T202532Z"
signature <- "<signature-string>"
region <- "us-east-1"

# 构造合规的Authorization Header(注意把%2F替换成/)
auth_header <- glue::glue(
  "AWS4-HMAC-SHA256 Credential={credential_string}/{substr(amz_date, 1, 8)}/{region}/s3/aws4_request, ",
  "SignedHeaders=host;x-amz-date, ",
  "Signature={signature}"
)

# 组装GET请求
req <- request(glue::glue("https://{bucket}.s3.amazonaws.com/{file_path}")) %>%
  req_headers(
    `Host` = glue::glue("{bucket}.s3.amazonaws.com"),
    `X-Amz-Date` = amz_date,
    `Authorization` = auth_header
  ) %>%
  req_perform()

# 查看响应结果
resp_body_string(req)

额外验证要点

  • 确保SignedHeaders里的header名称全为小写,实际请求header的大小写不影响(AWS会统一转小写处理)。
  • 检查Host header的值必须和请求域名完全一致,不能带多余路径或参数。
  • 确认X-Amz-Date的值和预签名URL里的完全相同,修改时间会直接导致签名失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:45:08