Sitemap
androvideo

Andro Video

Google Cloud Storage Signed URL

--

最近公司使用 Google Cloud Storage 的服務來儲存檔案,但要如何提供使用者下載檔案呢?

Google Cloud Storage 提供了以下選項的存取控制:
• IAM權限:允許存取 Project 裡的所有 bucket 和 object。透過 IAM,您可以控制對整個 project 所有 bucket 和 object 的存取權限, 但是無法針對個別 bucket 或是 object 做控制
• Access control list(ACL):允許對各個 bucket 和 objects 進行讀寫的存取。當您需詳細地控制個別的資源時,可以使用 ACL。
• Signed URL:透過被產生的 URL 網址可以進行存取和讀寫。無論取得共享網址的人是否擁有Google 帳戶,每個取得共享網址的人皆可在特定的時間存取 object。
• Signed policy document:指定可以上傳到 bucket 的內容。在政策文件中,可以比 Signed URL 更精準地掌握像是檔案大小、內容類型等上傳特徵。網站擁有者可透過 Signed policy document 允許訪問者將檔案上傳到 Google Cloud Storage。

Signed URL 比較接近我們需要的使用情境,要如何產生呢?

你可以自行寫程式產生

Get Julien Chen’s stories in your inbox

Join Medium for free to get updates from this writer.

node.js 範例:

var crypto = require("crypto");
var fs = require("fs");

var expiry = new Date().getTime() + 3600;
var key = 'the_target_file';
var bucketName = 'bucket_name';
var accessId = 'my_access_id';
var stringPolicy = "GET\n" + "\n" + "\n" + expiry + "\n" + '/' + bucketName + '/' + key;
var base64Policy = Buffer(stringPolicy, "utf-8").toString("base64");
var privateKey = fs.readFileSync("gcs.pem","utf8");
var signature = encodeURIComponent(crypto.createSign('sha256').update(stringPolicy).sign(privateKey,"base64"));
var signedUrl = "https://" + bucketName + ".commondatastorage.googleapis.com/" + key +"?GoogleAccessId=" + accessId + "&Expires=" + expiry + "&Signature=" + signature;

console.log(signedUrl);

PHP 範例:

$expiry = time() + 3600;
$key = 'the_target_file';
$bucketName = 'bucket_name';
$accessId = 'my_access_id';
$stringPolicy = "GET\n\n\n".$expiry."\n/".$bucketName."/".$key;
$fp = fopen('gcs.pem', 'r');
$priv_key = fread($fp, 8192);
fclose($fp);
$pkeyid = openssl_get_privatekey($priv_key,"password");
if (openssl_sign( $stringPolicy, $signature, $pkeyid, 'sha256' )) {
$signature = urlencode( base64_encode( $signature ) );
echo 'https://'.$bucketName.'.commondatastorage.googleapis.com/'.
$key.'?GoogleAccessId='.$accessId.'&Expires='.$expiry.'&Signature='.$signature;
}

或是根據你後端程式語言尋找相對應的套件,以筆者所使用的 golang 為例,官方的 GCS 套件 cloud.google.com/go/storage 就內建 storage.SignedURL( bucketName, filename, options ) 的函式庫,只需要照填就能輕鬆產生 Signed URL 了。

bkt := "bucket_name"
filename := "file_name"
method := "GET"
expires := time.Now().Add(time.Second * 60)
url, err := storage.SignedURL(bkt, filename, &storage.SignedURLOptions{
GoogleAccessID: "example@developer.gserviceaccount.com",
PrivateKey: []byte("-----BEGIN PRIVATE KEY-----\nCAFasfdsafFDSAFDANBgk......."),
Method: method,
Expires: expires,
})
if err != nil {
// TODO: Handle error.
}
fmt.Println(url)

--

--