本頁面概述簽章網址,並說明如何搭配 Cloud CDN 使用。已簽署的網址可讓任何擁有該網址的人,無論有無 Google 帳戶,都能在期限內透過網址取得資源存取權。
已簽署網址可提供有限的權限和時間來提出要求。簽署網址的查詢字串中包含驗證資訊,因此使用者不需要任何憑證,也能對資源執行特定動作。產生已簽署網址時,您指定的使用者或服務帳戶必須具備足夠的權限,可提出與該網址相關的要求。
產生已簽署網址後,任何擁有該網址的人員都可以使用已簽署網址執行特定動作 (例如讀取物件),但須在特定時段內完成。
已簽署網址也支援選用的 URLPrefix
參數,可讓您根據通用前置字元提供多個網址的存取權。
如要將存取權範圍限定為特定網址前置字元,請考慮使用已簽署的 Cookie。
事前準備
使用已簽署的網址前,請先完成下列步驟:
確認已啟用 Cloud CDN;如需操作說明,請參閱「使用 Cloud CDN」。啟用 Cloud CDN 前,您可以在後端設定簽章網址,但必須啟用 Cloud CDN 才會生效。
請視需要更新至最新版 Google Cloud CLI:
gcloud components update
如需總覽,請參閱已簽署的網址和已簽署的 Cookie。
設定已簽署的要求金鑰
如要建立已簽署網址或已簽署 Cookie 的金鑰,您必須完成以下幾個步驟。
安全性考量
在下列情況下,Cloud CDN 不會驗證要求:
- 要求未簽署。
- 要求所用的後端服務或後端值區未啟用 Cloud CDN。
簽署的要求一律須先在來源端經過驗證,才能提供回應。這是因為來源可用於提供簽署和未簽署的混合內容,且用戶端可能會直接存取來源。
- Cloud CDN 不會封鎖沒有
Signature
查詢參數或Cloud-CDN-Cookie
HTTP Cookie 的要求。並拒絕要求參數無效 (或格式錯誤) 的要求。 - 應用程式偵測到無效簽章時,請確保應用程式會以
HTTP 403 (Unauthorized)
回應代碼回應。HTTP 403
回應代碼無法快取。 - 系統會分別快取已簽署和未簽署要求的回應,因此絕不會使用有效已簽署要求的成功回應,來處理未簽署的要求。
- 如果應用程式將可快取的回應代碼傳送至無效要求,日後有效的要求可能會遭到誤拒。
如果是 Cloud Storage 後端,請務必移除公開存取權,這樣 Cloud Storage 才能拒絕缺少有效簽章的要求。
下表摘要說明相關行為。
要求已簽署 | 快取命中 | 行為 |
---|---|---|
否 | 否 | 轉送至後端來源。 |
否 | 是 | 從快取提供。 |
是 | 否 | 驗證簽名。如果有效,則轉送至後端來源。 |
是 | 是 | 驗證簽名。如果有效,則從快取提供。 |
建立已簽署的要求金鑰
如要啟用 Cloud CDN 已簽署的網址和已簽署的 Cookie 支援,請在啟用 Cloud CDN 的後端服務及/或後端值區中建立一或多組金鑰。
在每個後端服務或後端值區中,請依據安全性需求指示建立和刪除金鑰。每個後端一次最多可設定三組金鑰。建議您定期輪替金鑰,方法是刪除最舊的金鑰、新增金鑰,並在簽署網址或 Cookie 時使用新金鑰。
您可以在多個後端服務和後端值區中使用相同的金鑰名稱,因為每組金鑰都是獨立的。金鑰名稱長度最多 63 個字元,如要命名金鑰,請使用 A-Z、a-z、0-9、_ (底線) 和 - (連字號) 字元。
建立金鑰時,請務必妥善保管,因為只要取得金鑰,就能建立 Cloud CDN 接受的已簽署網址或已簽署 Cookie,直到金鑰從 Cloud CDN 刪除為止。金鑰會儲存在產生已簽署網址或已簽署 Cookie 的電腦上。Cloud CDN 也會儲存金鑰,用於驗證要求簽章。
為確保金鑰安全,任何 API 要求的相關回應都不會包含金鑰值。如果您失去金鑰,則必須建立新的金鑰。
如要建立簽署要求金鑰,請按照下列步驟操作。
主控台
- 前往 Google Cloud 控制台的「Cloud CDN」頁面。
- 按一下要新增金鑰的來源名稱。
- 在「來源詳細資料」頁面上,按一下「編輯」按鈕。
- 在「來源基本資訊」部分,按一下「下一步」,開啟「主機與路徑規則」部分。
- 在「主機與路徑規則」部分中,按一下「下一步」,開啟「快取效能」部分。
- 在「受限制的內容」部分,選取「透過已簽署的網址和 Cookie 限制存取權限」。
按一下「新增簽署金鑰」。
- 為新的簽署金鑰指定專屬名稱。
在「金鑰建立方法」部分,選取「自動產生」。 或者,按一下「讓我輸入」,然後指定簽署金鑰值。
如果是前者,請將自動產生的簽署金鑰值複製到私密檔案,以便建立已簽署的網址。
按一下 [完成]。
在「Cache entry maximum age」(快取項目存在時間長度上限) 區段中輸入值,然後選取時間單位。
按一下 [完成]。
gcloud
gcloud
指令列工具會從您指定的本機檔案讀取金鑰。金鑰檔案必須透過產生 128 位元的強隨機數、以 Base64 編碼,然後將字元 +
替換為 -
,並將字元 /
替換為 _
來建立。詳情請參閱 RFC 4648。金鑰必須是強隨機。在 UNIX 等系統上,您可以使用下列指令來產生高度隨機金鑰並將其儲存在金鑰檔案中:
head -c 16 /dev/urandom | base64 | tr +/ -_ > KEY_FILE_NAME
如要將金鑰新增至後端服務,請按照下列步驟操作:
gcloud compute backend-services \ add-signed-url-key BACKEND_NAME \ --key-name KEY_NAME \ --key-file KEY_FILE_NAME
如要將金鑰新增至後端 bucket:
gcloud compute backend-buckets \ add-signed-url-key BACKEND_NAME \ --key-name KEY_NAME \ --key-file KEY_FILE_NAME
設定 Cloud Storage 權限
如果您使用 Cloud Storage,並已限制哪些使用者可以讀取物件,則必須將 Cloud CDN 服務帳戶新增至 Cloud Storage ACL,藉此授予 Cloud CDN 讀取物件的權限。
您不需要建立服務帳戶。在您首次將金鑰新增至專案後端值區時,系統就會自動建立服務帳戶。
執行下列指令前,請先在專案的後端值區中加入至少一個金鑰,否則,指令就會失敗並發生錯誤,因為您必須先為專案新增一或多個金鑰,系統才會建立 Cloud CDN 快取填補服務帳戶。
gcloud storage buckets add-iam-policy-binding gs://BUCKET \ --member=serviceAccount:service-PROJECT_NUM@cloud-cdn-fill.iam.gserviceaccount.com \ --role=roles/storage.objectViewer
將 PROJECT_NUM
替換為專案編號,並將 BUCKET
替換為儲存空間值區。
Cloud CDN 服務帳戶 service-PROJECT_NUM@cloud-cdn-fill.iam.gserviceaccount.com
不會顯示在專案的服務帳戶清單中。這是因為 Cloud CDN 服務帳戶為 Cloud CDN 所擁有,而非為您的專案所擁有。
如要進一步瞭解專案編號,請參閱 Google Cloud 主控台說明文件中的「尋找專案 ID 與專案編號」一文。
自訂快取時間上限
無論後端的 Cache-Control
標頭為何,Cloud CDN 都會快取已簽署要求的回應。在您為回應設定可快取時間長度上限標記之後,使用者不必重新驗證該網址即可加以快取。系統預設的可快取時間長度上限為 1 小時,不過您可以按照下列步驟修改這項設定。signed-url-cache-max-age
如要設定後端服務或後端值區的快取時間長度上限,請執行下列任一指令:
gcloud compute backend-services update BACKEND_NAME --signed-url-cache-max-age MAX_AGE
gcloud compute backend-buckets update BACKEND_NAME --signed-url-cache-max-age MAX_AGE
列出已簽署的要求金鑰名稱
如要列出後端服務或後端值區的鍵,請執行下列任一指令:
gcloud compute backend-services describe BACKEND_NAME
gcloud compute backend-buckets describe BACKEND_NAME
刪除已簽署的要求金鑰
透過特定金鑰簽署的網址失效之後,請執行下列其中一個指令,從後端服務或後端值區中刪除該組金鑰:
gcloud compute backend-services \ delete-signed-url-key BACKEND_NAME --key-name KEY_NAME
gcloud compute backend-buckets \ delete-signed-url-key BACKEND_NAME --key-name KEY_NAME
簽署網址
最後一個步驟是簽署並發布網址。您可以使用 gcloud compute sign-url
指令或自行編寫的程式碼簽署網址。如果您需要大量簽署網址,自訂程式碼可提供更優異的效能。
建立已簽署的網址
請依據下列操作說明,使用 gcloud compute sign-url
指令建立已簽署的網址。此步驟假設您已建立金鑰。
主控台
您無法使用 Google Cloud 控制台建立已簽署的網址。您可以透過 Google Cloud CLI 或使用下列範例撰寫自訂程式碼。
gcloud
Google Cloud CLI 包含可用來簽署網址的指令。如需這項指令的實作演算法說明,請參閱編寫自有程式碼的相關段落。
gcloud compute sign-url \ "URL" \ --key-name KEY_NAME \ --key-file KEY_FILE_NAME \ --expires-in TIME_UNTIL_EXPIRATION \ [--validate]
這項指令會從 KEY_FILE_NAME
讀取及解碼 base64url 編碼的金鑰值,並輸出已簽署的網址。您可以將該網址用於指定網址的 GET
或 HEAD
要求。
例如:
gcloud compute sign-url \ "https://example.com/media/video.mp4" \ --key-name my-test-key \ --expires-in 30m \ --key-file sign-url-key-file
URL
必須是含有路徑元件的有效網址。舉例來說,http://example.com
無效,但 https://example.com/
和 https://example.com/whatever
都是有效的網址。
如果提供選用的 --validate
標記,這項指令會使用產生的網址傳送 HEAD
要求,並列印 HTTP 回應碼。如果簽署的網址正確,回應代碼會與後端傳送的結果代碼相同。如果回應代碼不同,請重新檢查 KEY_NAME
和指定檔案的內容,並確認 TIME_UNTIL_EXPIRATION
的值至少為幾秒。
如未提供 --validate
旗標,系統不會驗證下列項目:
- 輸入內容
- 產生的網址
- 產生的已簽署網址
以程式輔助方式建立已簽署的網址
下列程式碼範例說明如何以程式輔助方式建立簽署網址。
Go
Ruby
.NET
Java
Python
PHP
以程式輔助方式建立含有網址前置字串的已簽署網址
以下程式碼範例說明如何以程式輔助方式,使用網址前置字元建立已簽署的網址。
Go
Java
Python
產生自訂已簽署網址
編寫自有的程式碼來產生已簽署的網址時,您的目標是建立採用以下格式或演算法的網址;所有網址參數都會區分大小寫,且必須按照顯示的順序排列:
https://example.com/foo?Expires=EXPIRATION&KeyName=KEY_NAME&Signature=SIGNATURE
如要產生已簽署網址,請按照下列步驟操作:
確保要簽署的網址不含
Signature
查詢參數。決定網址的到期時間,並附加有所需到期時間的
Expires
查詢參數。到期時間以世界標準時間為準,並為從 1970-01-01 00:00:00 UTC 起算的秒數。為了儘可能提升安全性,請根據您的用途將這個值設為可能的最短時間範圍。已簽署網址的有效期限越長,取得網址的使用者與其他人分享這個網址的風險就越高,無論是不小心或其他原因都有可能。設定金鑰名稱。網址必須使用提供該網址的後端服務或後端值區金鑰簽署。建議您使用最近新增的金鑰進行金鑰輪替。在網址中附加
&KeyName=KEY_NAME
,即可新增金鑰。將KEY_NAME
替換為在「建立簽署要求金鑰」中建立的所選金鑰名稱。簽署網址。請按照下列步驟建立已簽署的網址。請確認查詢參數的順序與步驟 1 之前顯示的順序相同,並確認簽署的網址中沒有任何大小寫變更。
a. 使用與您先前選擇的金鑰名稱相對應的密鑰,透過 HMAC-SHA1 雜湊處理整個網址 (包含開頭的
http://
或https://
以及結尾的&KeyName...
)。請使用原始的 16 位元組密鑰,而非 base64url 編碼金鑰。如有需要,請將金鑰解碼。b. 使用 base64url 編碼將結果編碼。
c. 將
&Signature=
附加至網址,後面接著已編碼的簽名。請勿將簽章的尾端=
字元轉換為百分比編碼形式%3D
。
使用已簽署網址的網址前置字元
您不必使用 Expires
和 KeyName
查詢參數簽署完整的要求網址,改為只簽署 URLPrefix
、Expires
和 KeyName
查詢參數即可。這樣一來,只要網址符合 URLPrefix
,即可在多個網址中重複使用 URLPrefix
、Expires
、KeyName
和 Signature
查詢參數的特定組合,不必為每個不同的網址建立新的簽章。
在下列範例中,醒目顯示的文字是您簽署的參數。Signature
會照常附加為最後一個查詢參數。
https://media.example.com/videos/id/master.m3u8?userID=abc123&starting_profile=1&URLPrefix=aHR0cHM6Ly9tZWRpYS5leGFtcGxlLmNvbS92aWRlb3Mv&Expires=1566268009&KeyName=mySigningKey&Signature=8NBSdQGzvDftrOIa3WHpp646Iis=
與簽署完整要求網址不同,使用 URLPrefix
簽署時,您不會簽署任何查詢參數,因此查詢參數可以自由加入網址。此外,與完整要求網址簽章不同的是,這些額外的查詢參數可以出現在組成簽章的查詢參數前後。因此,以下也是有效的網址,並加上已簽署網址前置字元:
https://media.example.com/videos/id/master.m3u8?userID=abc123&URLPrefix=aHR0cHM6Ly9tZWRpYS5leGFtcGxlLmNvbS92aWRlb3Mv&Expires=1566268009&KeyName=mySigningKey&Signature=8NBSdQGzvDftrOIa3WHpp646Iis=&starting_profile=1
URLPrefix
代表網址安全 Base64 編碼的網址前置字串,涵蓋簽章應適用的所有路徑。
URLPrefix
會編碼通訊協定 (http://
或 https://
)、FQDN 和選用路徑。路徑結尾是否要加上 /
為選填項目,但建議加上。前置字元不應包含查詢參數或片段,例如 ?
或 #
。
舉例來說,https://media.example.com/videos
會比對下列兩者的要求:
https://media.example.com/videos?video_id=138183&user_id=138138
https://media.example.com/videos/137138595?quality=low
前置字串的路徑會當做文字子字串使用,而非嚴格的目錄路徑。
舉例來說,前置字串 https://example.com/data
會授予下列兩項的存取權:
/data/file1
/database
為避免發生這類錯誤,建議您一律以 /
結尾,除非您有意選擇以部分檔案名稱 (例如 https://media.example.com/videos/123
) 結尾,以便授予下列項目的存取權:
/videos/123_chunk1
/videos/123_chunk2
/videos/123_chunkN
如果要求的網址與 URLPrefix
不符,Cloud CDN 會拒絕要求,並向用戶端傳回 HTTP 403
錯誤。
驗證已簽署的網址
驗證已簽署網址的程序基本上與產生已簽署網址的程序相同。舉例來說,假設您想驗證下列簽署網址:
https://example.com/PATH?Expires=EXPIRATION&KeyName=KEY_NAME&Signature=SIGNATURE
您可以使用 KEY_NAME
命名的私密金鑰,獨立產生下列網址的簽章:
https://example.com/PATH?Expires=EXPIRATION&KeyName=KEY_NAME
然後確認是否與 SIGNATURE
相符。
假設您要驗證具有 URLPrefix
的已簽署網址,如下所示:
https://example.com/PATH?URLPrefix=URL_PREFIX&Expires=EXPIRATION&KeyName=KEY_NAME&Signature=SIGNATURE
首先,請確認 URL_PREFIX
的 Base64 解碼值是 https://example.com/PATH
的前置字元。如果是,您就可以計算下列項目的簽章:
URLPrefix=URL_PREFIX&Expires=EXPIRATION&KeyName=KEY_NAME
然後確認是否與 SIGNATURE
相符。
如果是以網址為準的簽署方法,簽章會是查詢參數的一部分,或是嵌入為網址路徑元件。在將要求傳送至來源之前,系統會從網址中移除簽章和相關參數。這樣可避免簽章在來源處理要求時,導致路由問題。如要驗證這些要求,您可以檢查 x-client-request-url
要求標頭,其中包含移除簽署元件前的原始 (已簽署) 用戶端要求網址。
移除 Cloud Storage bucket 的公開存取權
為使已簽署的網址能妥善保護內容,原始伺服器不得授予該內容的公開存取權。使用 Cloud Storage 值區時,常見的做法是將物件設為暫時公開存取,以便進行測試。啟用已簽署的網址後,請務必移除值區中 allUsers
(和 allAuthenticatedUsers
,如果有的話) 的 READ 權限 (也就是儲存空間物件檢視者身分與存取權管理角色)。
停用值區的公開存取權之後,個別使用者如果具備存取權限 (例如 OWNER 權限),便可繼續存取 Cloud Storage,而不需要已簽署的網址。
如要移除 Cloud Storage bucket 的公開 allUsers
READ 存取權,請反向操作「將 bucket 中的所有物件設為可公開讀取」一節所述的動作。
發布及使用已簽署的網址
從 Google Cloud CLI 傳回或是您透過自訂程式碼產生的網址可依據您的需求發布。建議您只簽署 HTTPS 網址,因為 HTTPS 提供安全傳輸,可防止簽署網址的 Signature
元件遭到攔截。同樣地,請務必透過安全傳輸通訊協定 (例如 TLS/HTTPS) 發布已簽署的網址。