使用预签名URL完成AWS分片上传时出现‘Signature Does Not Match’错误
我之前也碰到过一模一样的坑!这种情况大概率是completeMultipartUpload请求的签名校验逻辑有几个容易忽略的细节没踩对,给你列几个最常见的排查方向:
严格匹配预签名时的请求方法和Content-Type
生成completeMultipartUpload的预签名URL时,你指定的是POST方法对吧?实际请求必须严格用POST,不能改成PUT或其他。另外,预签名时如果指定了Content-Type(比如application/xml),实际请求的Content-Type请求头必须完全一致——哪怕多了个; charset=utf-8或者大小写不一样,都会触发签名不匹配。确保请求体XML完全符合AWS规范
completeMultipartUpload的请求体是XML格式,这里有两个极易出错的点:<Part>节点的顺序必须和你上传分片的顺序完全一致;- 每个
<ETag>的值必须和分片上传成功后返回的ETag完全匹配(包括引号!比如必须写<ETag>"abc123"</ETag>,不能省略引号)。
给你一个正确的示例:
<CompleteMultipartUpload> <Part> <PartNumber>1</PartNumber> <ETag>"abc123"</ETag> </Part> <Part> <PartNumber>2</PartNumber> <ETag>"def456"</ETag> </Part> </CompleteMultipartUpload>如果XML里有多余的空格、换行或者标签顺序错误,AWS的签名校验会计算出不一致的结果,直接返回签名不匹配。
预签名参数与实际请求必须完全一致
生成预签名URL时如果指定了自定义header(比如x-amz-server-side-encryption),实际请求必须带上完全相同的header和值,不能多也不能少。另外,预签名URL中的uploadId必须和创建分片上传任务时拿到的uploadId完全一致,哪怕一个字符错误都不行。统一签名版本和凭证
确认所有步骤(创建分片、上传分片、complete)使用的是同一个AWS签名版本(现在主流是Signature Version 4),且用的是同一组Access Key/Secret Key。如果中间换了凭证或签名版本,也会导致签名校验失败。不要手动修改预签名URL
预签名URL生成后,绝对不能手动修改其中的任何参数(比如Expires时间、Signature段),也不能额外添加查询参数,否则签名肯定对不上。
我当时就是因为XML里的ETag没加引号,折腾了好半天😂 你可以先从XML结构和Content-Type这两点查起,大概率能解决问题。
内容的提问来源于stack exchange,提问作者PandaScript

