全部產品
Search
文件中心

Object Storage Service:Browser.js授權訪問

更新時間:Feb 28, 2024

本文介紹如何使用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的步驟如下:

  1. 搭建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")
    })

  2. 用戶端使用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)?

  1. 產生上傳的檔案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();
    
  2. 使用簽名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>
    

相關文檔

  • 關於使用STS進行臨時授權訪問的完整範例程式碼,請參見GitHub樣本

  • 關於使用簽名URL進行臨時授權訪問的完整範例程式碼,請參見GitHub樣本