AWS SDK V2与V3预签名URL文件上传签名不匹配问题排查
AWS SDK V3预签名URL上传文件失败:签名不匹配问题解决
问题现象
使用AWS SDK V3生成的预签名URL无法完成S3文件上传,SDK V2的相同逻辑可以正常工作,但V3上传时返回错误:
The request signature we calculated does not match the signature you provided. Check your key and signing method.
代码对比
AWS SDK V2 可正常工作的代码
await s3Client.getSignedUrlPromise('putObject', { Bucket: process.env.S3Bucket, Key: req.body.filename, ContentType: req.body.filetype, Expires: DAY, }); // 生成的URL示例: // https://trc-erc-stackprod-filess3bucket-1b5q2jbcvvzlj.s3.amazonaws.com/applications/7105/1697349391787.pdf?AWSAccessKeyId={key}&Content-Type=application%2Fpdf&Expires=1697439459&Signature={signature}
AWS SDK V3 存在问题的代码
await getSignedUrl( s3, new PutObjectCommand({ Bucket: process.env.S3Bucket, Key: req.body.filename, ContentType: req.body.filetype, }), {expiresIn: DAY} ) // 生成的URL示例: // https://trc-erc-stackprod-filess3bucket-1b5q2jbcvvzlj.s3.us-east-1.amazonaws.com/applications/7105/1697349391787.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential={credentials}&X-Amz-Date=20231015T065739Z&X-Amz-Expires=900&X-Amz-Signature={signature}&X-Amz-SignedHeaders=expires%3Bhost&x-id=PutObject
前端Axios上传代码(问题版本)
await axios.put(presignedUrl, _file, { params: { name: key, }, headers: { 'Content-Type': _file.type, } })
问题原因
AWS预签名URL的签名是基于生成时的请求参数计算的。V3版本的签名算法对请求参数的变更更为敏感,前端Axios请求中额外添加的params: {name: key}会修改实际请求的URL参数,导致签名验证不通过。而V2的签名逻辑在该场景下兼容性更强,未触发错误。
解决方案
移除Axios请求中的额外params参数,确保实际请求URL与预签名URL完全一致:
await axios.put(presignedUrl, _file, { headers: { 'Content-Type': _file.type, } })
内容的提问来源于stack exchange,提问作者Travis Delly
相关产品推荐
相关产品推荐

