簡體   English   中英

重定向到簽名雲存儲 URL (cURL?) 的問題

[英]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 請求時會發生什么,導致簽名的這種差異?

如果我理解正確,問題出現在兩種情況下

  1. 當通過 curl 擊中你的 CF 時
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

然后我在郵遞員上嘗試了 GET 並且工作得很好。 在此處輸入圖片說明

我還嘗試使用簽名 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM