各位讀者好
你是否也遇過這個常見的挑戰:儲存在 Google Cloud Storage (GCS) 私有值區 (Private Bucket) 中的檔案,需要暫時提供給特定使用者或外部應用程式下載,但又不想將整個值區或物件設為公開,更不想為此建立複雜的 IAM 權限?
在這個情況下我們可以使用 Signed URL (簽署網址)!🔐
Signed URL 是一個帶有時效性的特殊網址,它將權限驗證資訊直接簽署在 URL 中。任何持有此 URL 的人,都可以在其過期前,暫時擁有下載(或上傳/刪除)該私有物件的權限,時間一到,網址自動失效。這是一種兼具安全、彈性與便利的存取控制方法。
今天,就讓我們來看看如何快速建立 GCS 的 Signed URL 吧!
開始之前:你需要什麼?
- 開啟所需的 API:使用 Signed URL 會需要開啟 IAM Service Account Credentials API (圖1)
- 服務帳戶 (Service Account):這是代表你的應用程式或服務執行操作的「機器人帳號」。我們會用它的金鑰來簽署 URL (圖2)
- 正確的 IAM 權限:服務帳戶本身至少需要具備以下之一的角色才能執行 Signed URL 設定。另外一定需要
roles/iam.serviceAccountTokenCreator
的角色進行 Token 生成
- Storage Object User (
roles/storage.objectUser
): Use this role to create signed URLs for both uploading and downloading objects. This role is also required if the signed URL could overwrite an existing object. - Storage Object Viewer (
roles/storage.objectViewer
): Use this role if you only want to create signed URLs for downloading objects. - Storage Object Creator (
roles/storage.objectCreator
): Use this role if you only want to create signed URLs for uploading objects and the uploaded object won't overwrite an existing object in the bucket.
- Storage Object User (

圖1

圖2
方法一:使用 gcloud CLI (最快速的開發測試方法)
對於開發者和維運人員來說,gcloud 命令列工具是最直接的方式。適合臨時產生 URL 進行測試。
指令範例:
gcloud storage sign-url gs://BUCKET_NAME/OBJECT_NAME --impersonate-service-account=SERVICE_ACCOUNT_EMAIL --duration=10m --region=asia-east1
參數說明:
- BUCKET_NAME is the name of the bucket where the object is located. For example, example-bucket.
- OBJECT_NAME is the name of the object to download. For example, cat.jpeg.
- SERVICE_ACCOUNT_EMAIL is the email address of a service account whose key will do the signing. For example, signed-url-account@my-project.iam.gserviceaccount.com.
Flag --duration 是指 Signed URL 的有效時間 (分鐘為單位)。以上面的範例來說,Signed URL 有效時間為 10 分鐘。
✨ 實際範例:假設我要分享 aws-me-sw Bucket 裡面的 me_files.zip,有效時間為 10 分鐘:
gcloud storage sign-url gs://aws-me-sw/me_files.zip --impersonate-service-account=forsignedurl@tw-xx-xx-xxxxxce.iam.gserviceaccount.com --duration=10m --region=asia-east1
執行後,你會在終端機得到一長串的 URL,直接將它交給使用者即可!

方法二:使用 Python Client Library (應用程式整合首選)
當你的應用程式需要動態產生下載連結時(例如,使用者點擊「下載發票」按鈕),就需要用程式碼來實現。
Python 程式碼範例:
import datetime
from google.cloud import storage
def generate_download_signed_url_v4(bucket_name, blob_name):
"""Generates a v4 signed URL for downloading a blob.
Note that this method requires a service account key file. You can not use
this if you are using Application Default Credentials from Google Compute
Engine or from the Google Cloud SDK.
"""
# bucket_name = 'your-bucket-name'
# blob_name = 'your-object-name'
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(blob_name)
url = blob.generate_signed_url(
version="v4",
# This URL is valid for 15 minutes
expiration=datetime.timedelta(minutes=15),
# Allow GET requests using this URL.
method="GET",
)
print("Generated GET signed URL:")
print(url)
print("You can use this URL with any user agent, for example:")
print(f"curl '{url}'")
return url
這段程式碼可以輕易地整合到你的 Web 應用程式後端 (如 Django, Flask),為使用者提供安全的檔案下載功能。
💡 最佳實踐與提醒
- 最小權限原則:賦予服務帳戶的權限越少越好。如果只是下載,roles/storage.objectViewer 就足夠。
- 最短有效時間:URL 的壽命應該盡可能短,滿足使用情境即可。不要設定長達數天或數週的下載連結。
- 保護 URL:Signed URL 就等同於一把臨時鑰匙。請透過 HTTPS 傳輸,並視其為敏感資訊,不要公開在網頁原始碼或日誌中。
- 優先使用 V4 簽署:V4 是目前最新、最安全的簽署流程,建議所有新應用程式都採用。
Signed URL 是管理雲端儲存權限的利器,讓你無需在安全與便利之間妥協。
你在什麼情境下會使用 Signed URL 呢?
歡迎在底下留言分享你的經驗或提出問題!👇