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

React Native上传阿里云OSS时预签名URL签名不匹配问题

React Native上传阿里云OSS出现SignatureDoesNotMatch错误排查与解决

问题背景

React Native 0.70.x应用上传图片到阿里云OSS前,先从Node.js/Express 20.x后端获取预签名URL。后端根据OSS文件名(作为object key)、内容类型(image/jpeg)和PUT请求方法生成预签名URL,但前端使用该URL发起PUT请求时,OSS持续返回403签名不匹配错误。

相关代码片段

后端生成预签名URL代码(存在语法错误)

// 注意:原代码存在语法错误,多了一个右括号
sUrl = store.signatureUrl(items[i][0]), { 
    expires: parseInt(process.env.OSSExpireIn), // 有效期3600s
    method: 'PUT',
    'Content-Type': _type // _type为image/jpeg
};

后端OSS存储实例定义

store: function() {
    try {
        let bucket_name = 'oss-1', region_name='oss-cn-xxxx'; 
        let store = OSS({
            accessKeyId: process.env.AliStsAccessKeyId,
            accessKeySecret: process.env.AliStsAccessKeySecret,
            bucket: bucket_name,
            region: region_name
        });
        return store;    
    } catch(err) {
        console.log("Error creating store with OSS", err);
        return false;
    };
}, 

前端上传代码(存在上传方式错误)

fileData = await ReactNativeBlobUtil.fs.readFile(filePath, 'base64');
const formData = new FormData();
formData.append('file', fileData, {type:contentTypeMap[extension]}); 
const response = await fetch(preSignedUrl, { 
    method: 'PUT',
    body: formData,
});

错误响应信息

前端控制台403响应

LOG  respnose in uploadtooss :  {"_bodyBlob": {"_data": {"__collector": [Object], "blobId": "f0071d9c-f218-4b26-bcaf-0d7e8983bbf3", "offset": 0, "size": 1127}}, "_bodyInit": {"_data": {"__collector": [Object], "blobId": "f0071d9c-f218-4b26-bcaf-0d7e8983bbf3", "offset": 0, "size": 1127}}, "bodyUsed": false, "headers": {"map": {"connection": "keep-alive", "content-length": "1127", "content-type": "application/xml", "date": "Thu, 08 Feb 2024 22:18:27 GMT", "server": "AliyunOSS", "x-oss-ec": "0002-00000040", "x-oss-request-id": "65C5533307D4B93635D7511C", "x-oss-server-time": "95"}}, "ok": false, "status": 403, "statusText": "", "type": "default", "url": "https://oss-hz-1.oss-cn-xxxxxx.aliyuncs.com/22790-fCWOVB_1000000021.jpg?OSSAccessKeyId=LTAI5t5axvqwo2qGnxxxxxxxx&Expires=1707432506&Signature=m60o9WszMIcfzF8mHWQ2HDPHsHW%3D"}

Postman测试返回的XML错误

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>SignatureDoesNotMatch</Code>
  <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
  <RequestId>646DCB189AE2D1333018****</RequestId>
  <HostId>bucket.oss-cn-xxxxx.aliyuncs.com</HostId>
  <OSSAccessKeyId>LTAI5tMw7e8syBazfpSS****</OSSAccessKeyId>
  <SignatureProvided>tPN3MChhvKk2XixolQLonoJW****</SignatureProvided>
  <StringToSign>PUT\n\n\nTue, 23 May 2023 15:24:55 GMT\n/bucket/?acl</StringToSign>
  <StringToSignBytes>50 55 54 0A 0A 0A 54 75 65 2C 20 32 33 20 4D 61 79 20 32 30 32 33 20 31 35 3A 32 34 3A 35 35 20 47 4D 54 0A 2F 64 69 6E 61 72 79 2F 3F 61 63 6C </StringToSignBytes>
  <EC>0002-00000040</EC>
</Error>

错误原因分析

  1. 后端代码语法错误:生成签名时的参数传递存在语法错误,多了一个右括号,导致Content-Type等参数未被正确传入签名计算逻辑。
  2. 前端上传方式错误:使用FormData作为PUT请求体不符合OSS预签名PUT的要求,OSS要求直接上传文件二进制内容,FormData会改变请求的Content-Type和请求体结构,导致签名校验不通过。
  3. Postman测试操作错误:从返回的StringToSign可以看出,测试时请求路径被错误附加了?acl参数,和预签名时的object key不匹配。

解决方案

1. 修复后端签名生成代码

修正语法错误,确保参数正确传递给signatureUrl方法:

sUrl = store.signatureUrl(items[i][0], {
    expires: parseInt(process.env.OSSExpireIn),
    method: 'PUT',
    'Content-Type': _type
});

2. 修改前端上传逻辑

直接上传文件二进制Blob,确保请求Content-Type与签名时完全一致:

// 读取文件为Blob格式
const blob = await ReactNativeBlobUtil.fs.readFile(filePath, 'blob');

const response = await fetch(preSignedUrl, {
    method: 'PUT',
    headers: {
        'Content-Type': 'image/jpeg' // 必须和签名时指定的Content-Type完全一致
    },
    body: blob // 直接传递二进制Blob,而非FormData
});

3. 规范Postman测试流程

  • 选择PUT请求,将图片以binary模式作为请求体上传
  • 使用正确的预签名URL,不要额外添加?acl等无关参数
  • 请求头中指定Content-Type: image/jpeg,与签名时保持一致

额外检查点

  • 确认后端生成签名时的object key与前端上传的目标路径完全一致,无多余字符或斜杠差异
  • 检查服务器时间与OSS服务器时间是否同步,时间差过大可能导致签名失效
  • 验证STS临时密钥是否具备PUT操作权限,bucket和region配置是否正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 13:15:06