调用API上传图片遭遇403 SignatureDoesNotMatch错误求助
排查Google Cloud Storage上传图片403 SignatureDoesNotMatch错误
先看错误返回中的关键提示:
<StringToSign>GET 1722666597 /</StringToSign>
这说明Google服务器收到的是GET请求,但API文档明确要求用PUT方法上传,这是导致签名不匹配的核心诱因之一,从以下方向逐一排查:
1. 确认请求方法严格为PUT
检查你的网络请求配置,确保.putPhoto分支对应的请求方法确实被设置为PUT,而非被错误默认成GET。部分网络框架会默认使用GET,需要显式指定PUT方法。
2. 验证Content-MD5与实际上传数据完全匹配
签名计算会关联Content-Md5的值,必须确保:
model.directUpload.headers.contentMD5是你要上传的image数据的MD5值(Base64编码格式)- 手动计算
image的MD5并与拿到的contentMD5对比验证,例如用Swift代码校验:import CommonCrypto func md5Base64(data: Data) -> String { var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) data.withUnsafeBytes { _ = CC_MD5($0.baseAddress, CC_LONG(data.count), &digest) } return Data(digest).base64EncodedString() } // 对比md5Base64(data: image)与model.directUpload.headers.contentMD5是否一致
如果两者不匹配,签名必然校验失败。
3. 确保Content-Type的处理符合要求
API文档中Content-Type为空值,需检查:
- 请求确实发送了
Content-Type:头,且值为空字符串 - 没有被网络框架自动填充默认的Content-Type(比如
application/octet-stream),部分框架会自动补全缺失的头,需要禁用该行为。
4. 确认请求体数据完整无异常
检查image数据是否为完整的图片二进制:
- 确认图片转Data的过程无错误(需是PNG/JPG原始二进制,而非Base64编码后的数据)
- 数据未被截断、追加额外字符或错误编码转换(比如误用utf8编码处理二进制数据)
5. 核对签名生成的上下文一致性
生成签名时的参数必须与请求完全对齐:
- 签名基于PUT请求上下文生成,若实际发送GET,服务器计算的签名自然与你提供的不匹配
- 资源路径、Expires时间、GoogleAccessId必须与请求URL中的参数完全一致
内容的提问来源于stack exchange,提问作者Emir
相关产品推荐
相关产品推荐

