Go生成S3预签名PUT URL遇SignatureDoesNotMatch 403错误
解决S3预签名PUT URL返回403 SignatureDoesNotMatch的问题
核心问题拆解
SignatureDoesNotMatch 本质是前端请求的参数/请求头和预签名URL生成时的配置不匹配,或是权限配置存在遗漏。以下是针对性的修复方案:
1. 对齐预签名与前端请求的Content-Type
你后端生成预签名时没指定Content-Type,但前端请求里加了"Content-Type": "multipart/form-data",这种不一致会直接导致签名校验失败。
后端代码修复:
在生成预签名时明确指定和前端一致的Content-Type:
req, err := presignClient.PresignPutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String("bucket-name-example"), Key: aws.String("randomFileName"), ContentType: aws.String("multipart/form-data"), // 和前端请求头保持一致 })
可选前端调整:
如果上传的是普通文件(图片、文档等),可以直接去掉Content-Type,让浏览器自动适配:
return await fetch(signedURLFromBackend, { method: "PUT", body: file, })
2. 补充桶策略的PUT权限
当前桶策略只允许s3:GetObject操作,即便IAM用户有全权限,预签名URL的请求仍会被桶策略拦截。需要添加PUT权限:
更新后的桶策略:
{ "Version": "2012-10-17", "Id": "Policy1675697346173", "Statement": [ { "Sid": "Stmt1675697339589", "Effect": "Allow", "Principal": "*", "Action": ["s3:GetObject", "s3:PutObject"], // 新增PutObject权限 "Resource": "arn:aws:s3:::userled-assets-library/*" } ] }
3. 检查服务器时间同步
AWS签名校验对时间敏感度很高,如果你的后端服务器和AWS服务器时间差超过5分钟,会直接触发签名不匹配错误。确保服务器开启NTP时间同步服务,保持时间准确。
4. 禁止前端添加未预签名的额外请求头
如果前端请求里加了预签名生成时没指定的自定义请求头,也会导致校验失败。确保前端的请求头完全匹配预签名时的配置,或是在预签名阶段明确包含这些请求头。
验证流程
- 重新生成预签名URL,确认Content-Type参数和前端一致
- 应用更新后的桶策略
- 测试前端PUT请求,观察错误是否消失
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

