重定向到签名云存储的问题 URL (cURL?)
Problems with redirecting to signed cloud storage URL (cURL?)
我正在创建一个 Firebase HTTP 函数,该函数将文件上传到云存储,为该文件创建一个签名 URL,然后将客户端重定向到该 URL。使用启用了自动重定向的 Postman,可以正确检索文件。但是,如果我在使用 cURL (curl -L -H "Content-Type: application/json" "https://us-central1-example.cloudfunctions.net/exampleFunction" -d '{"example": true}'
) 时尝试打开重定向,Cloud Storage 会返回以下错误:
<?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 Google secret key and signing method.</Message>
<StringToSign>GET
application/json
1602245678
/example.appspot.com/exampleBucket/exampleFile.txt</StringToSign>
</Error>
如果我改为使用表单编码数据发出请求,它也适用于 cURL:curl -L "https://us-central1-example.cloudfunctions.net/exampleFunction" -d "example=true"
如果我尝试在 Postman 中手动向 URL 发出 GET 请求,我会得到一个等效的错误:
<?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 Google secret key and signing method.</Message>
<StringToSign>GET
1602246219
/www.google.com/example.appspot.com/exampleBucket/exampleFile.txt</StringToSign>
</Error>
如果我将 URL 粘贴到浏览器或使用 cURL 下载已签名的 URL,文件也会正确下载。
我正在使用以下函数来获取签名 url:
async getSignedUrl(file: File, expireAt: number): Promise<string> {
const [url] = await file
.getSignedUrl({
action: "read",
expires: expireAt
});
return url
}
其中 returns 签名 URL 格式如下:
https://storage.googleapis.com/example.appspot.com/exampleBucket/exampleFile.txt?GoogleAccessId=[Access ID]&Expires=1602246219&Signature=[Signature]
(我注意到“Expires”的值与代码中返回的值相同)。
我怀疑 Postman 和 cURL 在请求中添加了一些东西导致了不同的签名,但我不确定到底发生了什么。
让 cURL 跟随重定向或在 Postman 中创建 GET 请求时发生了什么,导致了这种签名差异?
如果我没理解错的话,问题出现在两种情况下
- 当通过 curl 使用
击中你的 CF 时
curl -L -H "Content-Type: application/json" "https://us-central1-example.cloudfunctions.net/exampleFunction" -d '{"example": true}')
根据example in github in the docs Signed URL v4,应该使用'Content-Type: application/octet-stream'
:
curl -X PUT -H 'Content-Type: application/octet-stream' --upload-file my-file '${url}'
我尝试了以下成功的结果:
curl -X PUT -H 'Content-Type: application/octet-stream' -d '{"example": true}' 'https://storage.googleapis.com/...'
如果我尝试使用您分享的 content-type
失败的结果。
2.
If I try to manually make a GET request to the URL in Postman, I get an equivalent error:
I tried a simple GET in postman using a Signed URL and it worked just fine
gsutil 中用于获取签名的命令 URL:
gsutil signurl -d 10m key.json gs://BUCKET/aa.png
我也尝试过使用 Signed URL 在 Postman 中上传文件并且工作得很好。
我的想法是,根据 Common MIME types
application/octet-stream is the default value for all other cases (not textual files).
当您将内容类型设置为 application/json 时,您指定的是 JSON 格式,而不是 object 或文件。这就是它与以下内容一起使用的原因,因为您没有指定 header content-type
,默认值为 application/octet-stream
curl -L "https://us-central1-example.cloudfunctions.net/exampleFunction" -d "example=true"
Joss Barons 答案帮助我朝着正确的方向前进,但 Content-Type
必须是 application/octet-stream
是不正确的。这仅用于创建可用于上传文件的签名 url。在我的例子中,当使用 Cloud Storage SDK for node 创建签名 url 时,我没有指定 Content-Type
,所以当向签名 url 发送 GET
请求时], 它不能包含 Content-Type
header.
我正在创建一个 Firebase HTTP 函数,该函数将文件上传到云存储,为该文件创建一个签名 URL,然后将客户端重定向到该 URL。使用启用了自动重定向的 Postman,可以正确检索文件。但是,如果我在使用 cURL (curl -L -H "Content-Type: application/json" "https://us-central1-example.cloudfunctions.net/exampleFunction" -d '{"example": true}'
) 时尝试打开重定向,Cloud Storage 会返回以下错误:
<?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 Google secret key and signing method.</Message>
<StringToSign>GET
application/json
1602245678
/example.appspot.com/exampleBucket/exampleFile.txt</StringToSign>
</Error>
如果我改为使用表单编码数据发出请求,它也适用于 cURL:curl -L "https://us-central1-example.cloudfunctions.net/exampleFunction" -d "example=true"
如果我尝试在 Postman 中手动向 URL 发出 GET 请求,我会得到一个等效的错误:
<?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 Google secret key and signing method.</Message>
<StringToSign>GET
1602246219
/www.google.com/example.appspot.com/exampleBucket/exampleFile.txt</StringToSign>
</Error>
如果我将 URL 粘贴到浏览器或使用 cURL 下载已签名的 URL,文件也会正确下载。
我正在使用以下函数来获取签名 url:
async getSignedUrl(file: File, expireAt: number): Promise<string> {
const [url] = await file
.getSignedUrl({
action: "read",
expires: expireAt
});
return url
}
其中 returns 签名 URL 格式如下:
https://storage.googleapis.com/example.appspot.com/exampleBucket/exampleFile.txt?GoogleAccessId=[Access ID]&Expires=1602246219&Signature=[Signature]
(我注意到“Expires”的值与代码中返回的值相同)。
我怀疑 Postman 和 cURL 在请求中添加了一些东西导致了不同的签名,但我不确定到底发生了什么。
让 cURL 跟随重定向或在 Postman 中创建 GET 请求时发生了什么,导致了这种签名差异?
如果我没理解错的话,问题出现在两种情况下
- 当通过 curl 使用 击中你的 CF 时
curl -L -H "Content-Type: application/json" "https://us-central1-example.cloudfunctions.net/exampleFunction" -d '{"example": true}')
根据example in github in the docs Signed URL v4,应该使用'Content-Type: application/octet-stream'
:
curl -X PUT -H 'Content-Type: application/octet-stream' --upload-file my-file '${url}'
我尝试了以下成功的结果:
curl -X PUT -H 'Content-Type: application/octet-stream' -d '{"example": true}' 'https://storage.googleapis.com/...'
如果我尝试使用您分享的 content-type
失败的结果。
2.
If I try to manually make a GET request to the URL in Postman, I get an equivalent error: I tried a simple GET in postman using a Signed URL and it worked just fine
gsutil 中用于获取签名的命令 URL:
gsutil signurl -d 10m key.json gs://BUCKET/aa.png
我也尝试过使用 Signed URL 在 Postman 中上传文件并且工作得很好。
我的想法是,根据 Common MIME types
application/octet-stream is the default value for all other cases (not textual files).
当您将内容类型设置为 application/json 时,您指定的是 JSON 格式,而不是 object 或文件。这就是它与以下内容一起使用的原因,因为您没有指定 header content-type
,默认值为 application/octet-stream
curl -L "https://us-central1-example.cloudfunctions.net/exampleFunction" -d "example=true"
Joss Barons 答案帮助我朝着正确的方向前进,但 Content-Type
必须是 application/octet-stream
是不正确的。这仅用于创建可用于上传文件的签名 url。在我的例子中,当使用 Cloud Storage SDK for node 创建签名 url 时,我没有指定 Content-Type
,所以当向签名 url 发送 GET
请求时], 它不能包含 Content-Type
header.