本文介紹如何使用STS以及簽名URL臨時授權訪問OSS資源。
重要
由於STS臨時帳號以及簽名URL均需設定有效時間長度,當您使用STS臨時帳號產生簽名URL執行相關操作(例如上傳、下載檔案)時,以最小的有效時間長度為準。例如您的STS臨時帳號的有效時間長度設定為1200秒、簽名URL設定為3600秒時,當有效時間長度超過1200秒後,您無法使用此STS臨時帳號產生的簽名URL上傳檔案。
使用STS進行臨時授權
OSS可以通過阿里雲STS(Security Token Service)進行臨時授權訪問。阿里雲STS是為雲端運算使用者提供臨時存取權杖的Web服務。通過STS,您可以為第三方應用或子使用者(即使用者身份由您自己管理的使用者)頒發一個自訂時效和許可權的訪問憑證。關於STS的更多資訊,請參見STS介紹。
STS的優勢如下:
您無需透露您的長期密鑰(AccessKey)給第三方應用,只需產生一個存取權杖並將令牌交給第三方應用。您可以自訂這個令牌的存取權限及有效期間限。
您無需關心許可權撤銷問題,存取權杖到期後自動失效。
通過STS臨時授權訪問OSS的步驟如下:
搭建STS Server。
// 通過STS服務產生臨時訪問憑證。臨時訪問憑證包括臨時存取金鑰(AccessKeyId和AccessKeySecret)和安全性權杖(SecurityToken)。 const { STS } = require('ali-oss'); const express = require("express"); const app = express(); app.get('/sts', (req, res) => { let sts = new STS({ // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 accessKeyId: process.env.OSS_ACCESS_KEY_ID, accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET }); // roleArn填寫角色ARN。 // policy填寫自訂權限原則。 // expiration用於設定臨時訪問憑證有效時間單位為秒,最小值為900,最大值以當前角色設定的最大會話時間為準。 // sessionName用於自訂角色會話名稱,用來區分不同的令牌,例如填寫為SessionTest。 sts.assumeRole('acs:ram::137918634953****:role/ossram', `{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:*" ], "Resource": [ "acs:oss:*:*:examplebucket", "acs:oss:*:*:examplebucket/*" ] } ] }`, '3600', 'SessionTest').then((result) => { console.log(result); res.set('Access-Control-Allow-Origin', '*'); res.set('Access-Control-Allow-METHOD', 'GET'); res.json({ AccessKeyId: result.credentials.AccessKeyId, AccessKeySecret: result.credentials.AccessKeySecret, SecurityToken: result.credentials.SecurityToken, Expiration: result.credentials.Expiration }); }).catch((err) => { console.log(err); res.status(400).json(err.message); }); }); app.listen(8000,()=>{ console.log("server listen on:8000") })
用戶端使用STS憑證建構簽章請求。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <body> <!--匯入SDK檔案--> <script type="text/javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.18.0.min.js" ></script> <script type="text/javascript"> // 填寫您的授權伺服器地址,例如http://127.0.0.1:8000/sts。 fetch("yourStsServer") .then((resp) => resp.json()) .then((result) => { const store = new OSS({ // 從STS服務擷取的臨時存取金鑰(AccessKey ID和AccessKey Secret)。 accessKeyId: result.AccessKeyId, accessKeySecret: result.AccessKeySecret, // 從STS服務擷取的安全性權杖(SecurityToken)。 stsToken: result.SecurityToken, // 填寫Bucket所在地區。以華東1(杭州)為例,設定region為oss-cn-hangzhou。 region: "oss-cn-hangzhou", // 填寫Bucket名稱,例如examplebucket。 bucket: "examplebucket", }); // 產生簽名URL。 // 填寫Object完整路徑,例如oss.png。Object完整路徑中不能包含Bucket名稱。 const url = store.signatureUrl("oss.png"); console.log(url); }); </script> </body> </html>
使用簽名URL進行臨時授權
重要
如果要在前端使用帶選擇性參數的簽名URL,請確保在服務端產生該簽名URL時設定的Content-Type與在前端使用時設定的Content-Type一致,否則可能出現SignatureDoesNotMatch錯誤。設定Content-Type的具體操作,請參見如何設定Content-Type(MIME)?。
產生上傳的檔案URL。
// 產生臨時訪問憑證。 const OSS = require("ali-oss"); const STS = require("ali-oss").STS; // const cors = require("cors"); const stsClient = new STS({ // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 accessKeyId: process.env.OSS_ACCESS_KEY_ID, accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET, }); // 填寫儲存空間名稱,例如examplebucket。 const bucket = "examplebucket"; // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。 const region = "yourRegion"; // 指定角色ARN。 const roleArn = "acs:ram::137918634953****:role/ossram"; const getSts = () => { stsClient .assumeRole( roleArn, `{ "Statement": [ { "Effect": "Allow", "Action": "*", "Resource": [ "acs:oss:*:*:examplebucket/*" ] } ] }`, 3000 //指定SecurityToken到期時間。 ) .then((r) => { console.log("send:", r.credentials); const { SecurityToken, AccessKeyId, AccessKeySecret } = r.credentials; const client = new OSS({ bucket, region, accessKeyId: AccessKeyId, accessKeySecret: AccessKeySecret, stsToken: SecurityToken, refreshSTSTokenInterval: 9000, }); // 指定上傳至Bucket的檔案名稱。 const url = client.asyncSignatureUrl("example.txt", { expires: 3600, method: "PUT", // 設定Content-Type。 "Content-Type": "text/plain;charset=UTF-8", }); console.log("url:", url); // client.put("example.txt", Buffer.from("body")).then((res) => { // console.log("res", res.url); // }); }); }; getSts();
使用簽名URL上傳檔案。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <body> <script src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.18.0.min.js"></script> <script> // 填寫步驟1產生的簽名URL。 const url = "yourSignatureUrl"; var xhr = new XMLHttpRequest(); xhr.open("PUT", url, true); xhr.onload = function () { // 請求結束後,在此處編寫處理代碼。 }; // xhr.send(null); xhr.send("string"); // xhr.send(new Blob()); // xhr.send(new Int8Array()); // xhr.send({ form: 'data' }); // xhr.send(document); </script> </body> </html>