全部產品
Search
文件中心

Object Storage Service:授權給第三方下載

更新時間:Jun 19, 2024

本文介紹在不提供資源擁有者所屬帳號的存取金鑰(AccessKey)的情況下,通過臨時訪問憑證以及簽名URL的方式授權第三方下載檔案(Object)。

臨時訪問憑證

OSS可以通過阿里雲STS(Security Token Service)進行臨時授權訪問。阿里雲STS是為雲端運算使用者提供臨時存取權杖的Web服務。通過STS,您可以為第三方應用或子使用者(即使用者身份由您自己管理的使用者)頒發一個自訂時效和許可權的訪問憑證。關於STS的更多資訊,請參見STS介紹

STS的優勢如下:

  • 您無需透露您的長期密鑰(AccessKey)給第三方應用,只需產生一個存取權杖並將令牌交給第三方應用。您可以自訂這個令牌的存取權限及有效期間限。

  • 您無需關心許可權撤銷問題,存取權杖到期後自動失效。

說明

您可以通過調用STS服務的AssumeRole介面或者使用各語言STS SDK來擷取臨時訪問憑證。臨時訪問憑證包括臨時存取金鑰(AccessKeyId和AccessKeySecret)和安全性權杖(SecurityToken)。臨時訪問憑證有效時間單位為秒,最小值為900,最大值以當前角色設定的最大會話時間為準。更多資訊,請參見設定角色最大會話時間

使用阿里雲SDK

以下僅列舉常見SDK的通過STS臨時授權第三方下載檔案的程式碼範例。關於其他SDK的通過STS臨時授權第三方下載檔案的程式碼範例,請參見SDK簡介

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.model.GetObjectRequest;
import java.io.File;

public class Demo {
    public static void main(String[] args) throws Throwable {
        // 以華東1(杭州)的外網Endpoint為例,其他Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已通過環境變數設定臨時存取金鑰(OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)以及安全性權杖(OSS_SESSION_TOKEN)。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 填寫Object完整路徑,例如exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
        String objectName = "exampleobject.txt";
        String pathName = "D:\\examplefile.txt";

        // 從STS服務擷取臨時訪問憑證後,您可以通過臨時存取金鑰和安全性權杖產生OSSClient。
        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {

            // 下載OSS檔案到本地檔案。如果指定的本地檔案存在則覆蓋,不存在則建立。
            // 如果未指定本地路徑,則下載後的檔案預設儲存到樣本程式所屬專案對應本地路徑中。
            ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(pathName));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;

// 運行本程式碼範例之前,請確保已通過環境變數配置從STS服務擷取的臨時存取金鑰(OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)以及安全性權杖(OSS_SESSION_TOKEN)。
$accessKeyId = getenv("OSS_ACCESS_KEY_ID");
$accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
$securityToken = getenv("OSS_SESSION_TOKEN");
// 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 填寫Bucket名稱,例如examplebucket。
$bucket = "examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑。
$object = "exampledir/exampleobject.txt";

try {
    $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken);
    // 通過STS臨時授權下載檔案。
    $content = $ossClient->getObject($bucket, $object);
    var_dump($content);
} catch (OssException $e) {
    print $e->getMessage();
}
const axios = require("axios");
const OSS = require("ali-oss");

// 在用戶端使用臨時訪問憑證初始化OSS用戶端,用於臨時授權訪問OSS資源。
const getToken = async () => {
  const token = await axios.get("http://localhost:9999/sts");
  const client = new OSS({
    // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,yourRegion填寫為oss-cn-hangzhou。
    region: "oss-cn-hangzhou",
    // 通過STS服務產生臨時訪問憑證。臨時訪問憑證包括臨時存取金鑰(AccessKeyId和AccessKeySecret)和安全性權杖(SecurityToken)。
    accessKeyId: token.data.AccessKeyId,
    accessKeySecret: token.data.AccessKeySecret,
    stsToken: token.data.SecurityToken,
    // 填寫Bucket名稱,例如examplebucket。
    bucket: "examplebucket",
    refreshSTSToken: async () => {
      const refreshToken = await axios.get("http://127.0.0.1:9999/sts");
      return {
        accessKeyId: refreshToken.data.AccessKeyId,
        accessKeySecret: refreshToken.data.AccessKeySecret,
        stsToken: refreshToken.data.SecurityToken,
      };
    },
  });
  return client;
};

// 擷取對象執行個體。
getToken().then((client) => {
  // 通過STS臨時授權下載檔案。
  const url = client.signatureUrl("exampleobject.txt");
  console.log(url);
});
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已通過環境變數設定臨時存取金鑰(OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)以及安全性權杖OSS_SESSION_TOKEN。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱,例如examplebucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# 填寫Object完整路徑和字串。Object完整路徑中不能包含Bucket名稱。
object_name = 'exampleobject.txt'

# 下載Object。
read_obj = bucket.get_object(object_name)
print(read_obj.read())      
package main

import (
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "os"
)

func main() {
    // 從環境變數中擷取臨時訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET、OSS_SESSION_TOKEN。
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // 建立OSSClient執行個體。
    // yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // 填寫Bucket名稱,例如examplebucket。
    bucketName := "examplebucket"
    // 填寫Object的完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
    objectName := "exampledir/exampleobject.txt"
    // 填寫本地檔案的完整路徑,例如D:\\localpath\\examplefile.txt。
    filepath := "D:\\localpath\\examplefile.txt"
    bucket,err := client.Bucket(bucketName)
    // 通過STS授權第三方下載檔案。
    err = bucket.GetObjectToFile(objectName,filepath)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("download success")
}
using Aliyun.OSS;
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已通過環境變數設定臨時存取金鑰(OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)以及安全性權杖OSS_SESSION_TOKEN。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
var securityToken = Environment.GetEnvironmentVariable("OSS_SESSION_TOKEN");
// 填寫Bucket名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
// 填寫本地檔案的完整路徑,例如D:\\localpath\\examplefile.txt。
var downloadFilename = "D:\\localpath\\examplefile.txt";

// 建立OSSClient執行個體。
var ossStsClient = new OssClient(endpoint, accessKeyId, accessKeySecret, securityToken);
try
{
    // 下載檔案到流。OssObject包含了檔案的各種資訊,如檔案所在的儲存空間、檔案名稱、中繼資料以及一個輸入資料流。
    var obj = client.GetObject(bucketName, objectName);
    using (var requestStream = obj.Content)
    {
        byte[] buf = new byte[1024];
        var fs = File.Open(downloadFilename, FileMode.OpenOrCreate);
        var len = 0;
        // 通過輸入資料流將檔案的內容讀取到檔案或者記憶體中。
        while ((len = requestStream.Read(buf, 0, 1024)) != 0)
        {
            fs.Write(buf, 0, len);
        }
        fs.Close();
    }
    Console.WriteLine("Get object succeeded");
}
catch (Exception ex)
{
    Console.WriteLine("Get object failed. {0}", ex.Message);
}

簽名URL

重要

由於STS臨時帳號以及簽名URL均需設定有效時間長度,當您使用STS臨時帳號產生簽名URL執行相關操作(例如上傳、下載檔案)時,以最小的有效時間長度為準。例如您的STS臨時帳號的有效時間長度設定為1200秒、簽名URL設定為3600秒時,當有效時間長度超過1200秒後,您無法使用此STS臨時帳號產生的簽名URL上傳檔案。

您可以將產生的簽名URL提供給訪客進行臨時訪問。產生簽名URL時,您可以自訂URL的到期時間來限制訪客的訪問時間長度。

在URL中加入簽名資訊,以便將該URL轉給第三方實現授權訪問。更多資訊,請參見在URL中包含簽名

重要

通過以下樣本產生的簽名URL中如果包含特殊符號+,可能出現無法正常訪問該簽名URL的現象。如需正常訪問該簽名URL,請將簽名URL中的+替換為%2B

使用OSS控制台

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇檔案管理 > 檔案清單

  4. 擷取檔案URL。

    • 擷取單個檔案URL

      1. 單擊目標檔案名稱。

      2. 詳情面板配置以下參數,然後單擊複製檔案URL

        參數

        說明

        到期時間

        當目標檔案為私人檔案時,需設定檔案URL的有效時間。

        取值範圍:60~32400

        單位:秒

        如果您希望擷取更長時效的檔案URL,建議使用命令列工具ossutil圖形化工具ossbrowser

        自有網域名稱

        如需確保第三方訪問圖片或網頁檔案時是預覽行為,請使用Bucket綁定的自訂網域名組建檔案URL。

        僅當Bucket綁定自訂網域名後可配置此項。更多資訊,請參見綁定自訂網域名

        使用HTTPS

        預設使用HTTPS協議組建檔案URL。如需使用HTTP協議組建檔案URL,請關閉使用HTTPS開關。

    • 批量擷取檔案URL

      1. 選中多個目標檔案,然後單擊匯出URL列表

      2. 匯出URL列表面板配置以下參數:

        參數

        說明

        是否編碼

        選擇是否對匯出的檔案URL進行URL編碼。通過URL編碼可以避免URL中包含特殊符號(例如+)時無法正常訪問URL的情況。

        使用HTTPS

        預設使用HTTPS協議組建檔案URL。如需使用HTTP協議組建檔案URL,請關閉使用HTTPS開關。

        到期時間

        當目標檔案為私人檔案時,需設定檔案URL的有效時間。

        取值範圍:60~32400

        單位:秒

        如果您希望擷取更長時效的檔案URL,建議使用命令列工具ossutil圖形化工具ossbrowser

        自有網域名稱

        如需確保第三方訪問圖片或網頁檔案時是預覽行為,請使用Bucket綁定的自訂網域名組建檔案URL。

        僅當Bucket綁定自訂網域名後可配置此項。更多資訊,請參見綁定自訂網域名

        傳輸加速網域名稱

        如果第三方涉及跨國或跨洋等超遠距離檔案訪問情境時,建議使用傳輸加速網域名稱組建檔案URL。

        僅當Bucket開啟傳輸加速後可配置此項。更多資訊,請參見開啟傳輸加速

      3. 單擊確定,然後將URL列表檔案儲存到本地。

  5. 將檔案URL分享給第三方進行下載。

使用阿里雲SDK

以下僅列舉常見SDK的通過簽名URL授權第三方下載檔案的程式碼範例。關於其他SDK的通過簽名URL授權第三方下載檔案的程式碼範例,請參見SDK簡介

<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;

// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$accessKeyId = getenv("OSS_ACCESS_KEY_ID");
$accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "yourEndpoint";
// 填寫Bucket名稱。
$bucket= "examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑。
$object = "exampleobject.txt";
// 設定簽名URL的有效時間長度為3600秒。
$timeout = 3600;
// 產生預覽的簽名URL,然後使用Bucket綁定的自訂網域名進行訪問。
$options= array(
    "response-content-disposition"=>"inline",);
// 產生下載的簽名URL。
/*$options = array(
    "response-content-disposition"=>"attachment",
);*/
try {
    $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
    $signedUrl = $ossClient->signUrl($bucket, $object, $timeout,'GET',$options);

} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n");               
const OSS = require("ali-oss");

const client = new OSS({
  // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,yourRegion填寫為oss-cn-hangzhou。
  region: "oss-cn-hangzhou",
  // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  // 填寫Bucket名稱,例如examplebucket。
  bucket: "examplebucket",
});


// 配置exampleobject.txt檔案HTTP頭中的Content-Disposition為attachment,實現瀏覽器訪問時自動下載檔案,並自訂下載後的檔案名稱。
// 如果您希望直接在瀏覽器中預覽檔案,設定檔HTTP頭中的Content-Disposition為inline並使用Bucket綁定的自訂網域名進行訪問。
const filename = "ossdemo.txt"; // 自訂下載後的檔案名稱。
const response = {
  "content-disposition": `attachment; filename=${encodeURIComponent(filename)}`,
};
// 填寫待下載Object的完整路徑,完整路徑中不能包含Bucket名稱。
const url = client.signatureUrl("exampleobject.txt", {
  // 設定到期時間為3600s。
  expires: 3600,
  response,
});
console.log(url);
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱,例如examplebucket。
bucket = oss2.Bucket(auth, 'yourEndpoint', 'examplebucket')
# 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
object_name = 'exampledir/exampleobject.txt'

# 指定Header。
headers = dict()
# 如果您希望實現瀏覽器訪問時自動下載檔案,並自訂下載後的檔案名稱,設定檔HTTP頭中的Content-Disposition為attachment
# headers['content-disposition'] = 'attachment'
# 如果您希望直接在瀏覽器中預覽檔案,設定檔HTTP頭中的Content-Disposition為inline並使用Bucket綁定的自訂網域名進行訪問。
headers['content-disposition'] = 'inline'

# 指定下載檔案名稱。
query_params = {'response-content-disposition': 'attachment; filename=example.txt'}

# 產生下載檔案的簽名URL,有效時間為60秒。
# 產生簽名URL時,OSS預設會對Object完整路徑中的正斜線(/)進行轉義,從而導致產生的簽名URL無法直接使用。
# 設定slash_safe為True,OSS不會對Object完整路徑中的正斜線(/)進行轉義,此時產生的簽名URL可以直接使用。
url = bucket.sign_url('GET', object_name, 60, headers=headers, slash_safe=True, params=query_params)
print('簽名url的地址為:', url)

# 使用簽名URL將Object下載到本地。
# 填寫本地檔案的完整路徑,例如D:\\localpath\\examplefile.txt。
# 如果未指定本地路徑只設定了本地檔案名稱(例如examplefile.txt),則下載後的檔案預設儲存到樣本程式所屬專案對應本地路徑中。
result = bucket.get_object_with_url_to_file(url, 'D:\\localpath\\examplefile.txt')
print(result.read())
package main

import (
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "os"
)

func HandleError(err error) {
    fmt.Println("Error:", err)
    os.Exit(-1)
}

func main() {
    // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // 建立OSSClient執行個體。
    // yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 填寫Bucket名稱,例如examplebucket。
    bucketName := "examplebucket"
    // 填寫檔案完整路徑,例如exampledir/exampleobject.txt。檔案完整路徑中不能包含Bucket名稱。
    objectName := "exampledir/exampleobject.txt"
    // 將Object下載到本地檔案,並儲存到指定的本地路徑中。如果指定的本地檔案存在會覆蓋,不存在則建立。
    bucket, err := client.Bucket(bucketName)
    if err != nil {
        HandleError(err)
    }

    // 產生用於下載的簽名URL,並指定簽名URL的有效時間為60秒。
    signedURL, err := bucket.SignURL(objectName, oss.HTTPGet, 60)
    if err != nil {
        HandleError(err)
    }
    fmt.Printf("Sign Url:%s\n", signedURL)
}
using Aliyun.OSS;
using Aliyun.OSS.Common;
// 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫Bucket名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
// 填寫Object下載到本地檔案的完整路徑。例如D:\\localpath\\examplefile.txt。如果指定的本地檔案存在會覆蓋,不存在則建立。
var downloadFilename = "D:\\localpath\\examplefile.txt";
// 建立OSSClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    var metadata = client.GetObjectMetadata(bucketName, objectName);
    var etag = metadata.ETag;
    // 產生簽名URL。
    var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
      {
        // 設定簽名URL到期時間,預設值為3600秒。
        Expiration = DateTime.Now.AddHours(1),
    };
    var uri = client.GeneratePresignedUri(req);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* 填寫Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/ 
    std::string GetobjectUrlName = "exampledir/exampleobject.txt";

    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);

    /* 設定簽名URL有效時間長度。*/
    std::time_t t = std::time(nullptr) + 1200;
    /* 產生簽名URL。*/
    auto genOutcome = client.GeneratePresignedUrl(BucketName, GetobjectUrlName, t, Http::Get);
    if (genOutcome.isSuccess()) {
        std::cout << "GeneratePresignedUrl success, Gen url:" << genOutcome.result().c_str() << std::endl;
    }
    else {
        /* 異常處理。*/
        std::cout << "GeneratePresignedUrl fail" <<
        ",code:" << genOutcome.error().Code() <<
        ",message:" << genOutcome.error().Message() <<
        ",requestId:" << genOutcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* 使用簽名URL下載檔案。*/
    auto outcome = client.GetObjectByUrl(genOutcome.result());

    if (!outcome.isSuccess()) {
        /* 異常處理。*/
        std::cout << "GetObjectByUrl fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}