[英]Google Cloud Storage Signed URLs — How to specify a maximum file size?
[英]Problems with redirecting to signed cloud storage URL (cURL?)
我正在創建一個 Firebase HTTP 函數,該函數將文件上傳到 Cloud Storage,創建該文件的簽名 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
}
它以以下格式返回簽名 URL: https://storage.googleapis.com/example.appspot.com/exampleBucket/exampleFile.txt?GoogleAccessId=[Access ID]&Expires=1602246219&Signature=[Signature]
: https://storage.googleapis.com/example.appspot.com/exampleBucket/exampleFile.txt?GoogleAccessId=[Access ID]&Expires=1602246219&Signature=[Signature]
(我已經注意到“Expires”的值與標簽中返回的值相同)。
我懷疑 Postman 和 cURL 在請求中添加了一些導致不同簽名的內容,但我不確定到底發生了什么。
當讓 cURL 跟隨重定向或在 Postman 中創建 GET 請求時會發生什么,導致簽名的這種差異?
如果我理解正確,問題出現在兩種情況下
curl -L -H "Content-Type: application/json" "https://us-central1-example.cloudfunctions.net/exampleFunction" -d '{"example": true}')
根據文檔Signed URL v4 中 github中的示例,應使用'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.
如果我嘗試手動向 Postman 中的 URL 發出 GET 請求,我會得到一個等效的錯誤:我在 postman 中使用簽名 URL 嘗試了一個簡單的 GET 並且它工作得很好
gsutil 中用於獲取簽名 URL 的命令:
gsutil signurl -d 10m key.json gs://BUCKET/aa.png
我還嘗試使用簽名 URL 在 Postman 中上傳文件並且工作正常。
我的想法是,根據常見的 MIME 類型
application/octet-stream 是所有其他情況(不是文本文件)的默認值。
當您將內容類型設置為 application/json 時,您指定的是 JSON 格式,但不是對象或文件。 這就是為什么它適用於以下內容,因為您沒有指定標頭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
標頭。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.