重定向至Cloud Storage签名URL遇SignatureDoesNotMatch问题排查
这个问题的核心在于:Cloud Storage的签名URL是严格基于请求的核心参数生成的,当实际请求的参数和生成签名时的预期参数不一致时,就会触发SignatureDoesNotMatch错误。我们来逐一拆解你遇到的两种场景:
1. 带-L和Content-Type: application/json的cURL请求失败
当你用cURL -L跟随重定向时,cURL会默认把原请求的Content-Type头传递给重定向后的请求。但你生成签名URL时,是针对纯GET请求(没有指定任何额外请求头),所以签名验证时的StringToSign会包含意外的application/json值,和生成签名时的预期不符。
从你给出的错误信息里也能看到:
return (<StringToSign>GET application/json 1602245678 /example.appspot.com/exampleBucket/exampleFile.txt</StringToSign> )
正常情况下,这个StringToSign里的application/json应该是空的(因为GET请求不需要Content-Type,生成签名时也没指定这个头)。
解决方案:
在cURL请求中添加--header "Content-Type:"来清除重定向时传递的Content-Type头,或者直接去掉原请求的Content-Type: application/json(毕竟原请求是触发重定向,后续的GET请求不需要这个头)。比如:
curl -L --header "Content-Type:" https://your-firebase-function-url
2. Postman手动GET请求签名URL失败
从错误信息的StringToSign可以看到:
return (<StringToSign>GET 1602246219 /www.google.com/example.appspot.com/exampleBucket/exampleFile.txt</StringToSign> )
这里的路径多了www.google.com/前缀,说明Postman在处理签名URL时,错误地把请求路径设置成了相对于某个Base URL(比如你之前设置过www.google.com作为Base URL)的路径,导致实际请求的资源路径和生成签名时的路径完全不符。
解决方案:
- 检查Postman的请求设置,确保你是直接使用完整的签名URL发起请求,没有设置多余的Base URL。
- 可以新建一个空白请求,直接粘贴签名URL进去再测试,避免之前的配置干扰。
补充说明:签名URL的验证逻辑
Cloud Storage生成签名URL时,会基于以下信息生成签名:
- 请求方法(这里是
GET) - 过期时间(
Expires参数) - 资源的完整路径(比如
/example.appspot.com/exampleBucket/exampleFile.txt) - 如果生成签名时指定了特定请求头(比如
Content-Type),这些头也会被包含在签名计算中
实际请求时,任何一项和生成时的预期不一致,都会导致签名验证失败。浏览器或直接cURL请求签名URL能成功,是因为它们发送的是最纯净的GET请求,没有额外的请求头,路径也完全正确。
内容的提问来源于stack exchange,提问作者Robin

