全部產品
Search
文件中心

Object Storage Service:OSS Go SDK V1

更新時間:Jan 24, 2026

推薦使用新發布的OSS Go SDK V2(alibabacloud-oss-go-sdk-v2),相較V1版本(aliyun-oss-go-sdk)在架構設計上進行了重大最佳化,簡化了身分識別驗證、請求重試、錯誤處理等底層操作邏輯,提供更靈活的參數配置方式和豐富的進階介面(如分頁器、傳輸管理器、File-like介面等),顯著提升開發效率和使用體驗。從V1升級到V2,請參見Go SDK V1到V2遷移指南。

快速接入

通過以下步驟快速接入OSS Go SDK V1。

image

準備環境

請參考Golang安裝下載和安裝Go編譯運行環境。推薦使用Go 1.13及以上版本。

  • Go 1.13及以上版本預設啟用模組模式管理組件依賴關係,無需手動設定GOPATH。

  • Go 1.12及以下版本需要設定GOPATH系統變數,並將其指向代碼目錄。

執行go version命令可查看Go版本。

安裝SDK

根據開發環境選擇合適的安裝方式。建議使用最新版本的SDK,確保程式碼範例正常運行。

go mod方式(推薦)

在go.mod檔案中添加以下依賴。以下以3.0.2版本為例,其他版本需替換為對應版本號碼。

require (
    github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
)

源碼方式

執行以下命令安裝SDK:

go get github.com/aliyun/aliyun-oss-go-sdk/oss

安裝過程中,介面不會列印提示,請耐心等待。如果安裝逾時,請再次執行以上命令。

配置訪問憑證

使用 RAM 使用者的 AccessKey 配置訪問憑證。

  1. 在 RAM 控制台,建立使用永久 AccessKey 訪問的 RAM 使用者,儲存 AccessKey,然後為該使用者授予 AliyunOSSFullAccess 許可權。

  2. 使用 RAM 使用者的 AccessKey 配置環境變數。

    Linux

    1. 在命令列介面執行以下命令,將環境變數設定追加到~/.bashrc 檔案中。

      echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc
      echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc
    2. 執行以下命令使變更生效。

      source ~/.bashrc
    3. 執行以下命令檢查環境變數是否生效。

      echo $OSS_ACCESS_KEY_ID
      echo $OSS_ACCESS_KEY_SECRET

    macOS

    1. 在終端中執行以下命令,查看預設Shell類型。

      echo $SHELL
    2. 根據預設Shell類型進行操作。

      Zsh
      1. 執行以下命令,將環境變數設定追加到 ~/.zshrc 檔案中。

        echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc
        echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc
      2. 執行以下命令使變更生效。

        source ~/.zshrc
      3. 執行以下命令檢查環境變數是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET
      Bash
      1. 執行以下命令,將環境變數設定追加到 ~/.bash_profile 檔案中。

        echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile
        echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile
      2. 執行以下命令使變更生效。

        source ~/.bash_profile
      3. 執行以下命令檢查環境變數是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET

    Windows

    CMD
    1. 在CMD中運行以下命令。

      setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID"
      setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"
    2. 運行以下命令,檢查環境變數是否生效。

      echo %OSS_ACCESS_KEY_ID%
      echo %OSS_ACCESS_KEY_SECRET%
    PowerShell
    1. 在PowerShell中運行以下命令。

      [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User)
      [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
    2. 運行以下命令,檢查環境變數是否生效。

      [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User)
      [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)

初始化用戶端

重要

根據策略調整,為提升OSS服務的合規性和安全性,自2025年3月20日起,新開通OSS服務的使用者在中國內地地區的Bucket將無法通過預設外網網域名稱調用資料操作類API(如上傳、下載檔案),需通過自訂網域名(CNAME)方式訪問OSS服務。使用HTTPS協議訪問(如控制台)時,還需為自訂網域名配置SSL認證。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
package main

// OSS Go SDK V1初始化用戶端樣本

import (
	"fmt"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {

	// 從環境變數中載入訪問憑證(需要設定OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)
	provider, _ := oss.NewEnvironmentVariableCredentialsProvider()

	// 建立OSS用戶端執行個體
	client, _ := oss.New(
		"<endpoint>",
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("<region-id>"),
	)

	// 列舉所有Bucket
	buckets, err := client.ListBuckets()
	if err != nil {
		fmt.Printf("列舉Bucket失敗: %v\n", err)
		return
	}

	// 輸出Bucket列表資訊
	fmt.Printf("共找到 %d 個Bucket:\n", len(buckets.Buckets))

	for _, bucket := range buckets.Buckets {
		fmt.Printf("%s\n", bucket.Name)
	}
}

用戶端配置

初始化用戶端時,可自訂Endpoint類型、設定逾時時間和串連數等配置參數,以滿足不同網路環境和效能需求。

點擊查看用戶端可配置的參數

參數

描述

方法

MaxIdleConns

最大閑置串連數。預設值為100。

oss.MaxConns

MaxIdleConnsPerHost

每個主機的最大閑置串連數。預設值為100。

oss.MaxConns

MaxConnsPerHost

每個主機的最大串連數。預設為空白。

oss.MaxConns

ConnectTimeout

HTTP連線逾時時間,單位為秒。預設值為10秒,0表示不逾時。

oss.Timeout

ReadWriteTimeout

HTTP讀取或寫入逾時時間,單位為秒。預設值為20秒,0表示不逾時。

oss.Timeout

IsCname

是否開啟將自訂網域名作為Endpoint,預設不開啟。

oss.UseCname

UserAgent

設定HTTP的User-Agent頭,預設值為aliyun-sdk-go。

oss.UserAgent

ProxyHost

Proxy 伺服器主機地址和連接埠開關。取值如下:

  • true:開啟Proxy 伺服器主機地址和連接埠。

  • false(預設值):關閉Proxy 伺服器主機地址和連接埠。

oss.AuthProxy

ProxyUser

Proxy 伺服器驗證的使用者名稱。

oss.AuthProxy

ProxyPassword

Proxy 伺服器驗證的密碼。

oss.AuthProxy

RedirectEnabled

HTTP重新導向開關。取值如下:

  • true(預設值):開啟HTTP重新導向。

  • false:關閉HTTP重新導向。

oss.RedirectEnabled

InsecureSkipVerify

SSL認證校正開關。取值如下:

  • true(預設值):忽略SSL認證校正。

  • false:開啟SSL認證校正。

oss.InsecureSkipVerify

IsEnableCRC

CRC資料校正開關。取值如下:

  • true(預設值):開啟CRC資料校正。

  • false:關閉CRC資料校正。

oss.EnableCRC

LogLevel

記錄層級。取值如下:

  • oss.LogOff

  • oss.Debug

  • oss.Error

  • oss.Warn

  • oss.Info

oss.SetLogLevel

使用內網網域名稱

初始化OSS用戶端時,將Endpoint指定為內網訪問網域名稱即可實現內網訪問。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
// 建立OSS用戶端執行個體
client, _ := oss.New(
	"<endpoint>",
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("<region-id>"),
)

使用自訂網域名

將Endpoint指定為自訂網域名,並在初始化用戶端時通過oss.UseCname(true)參數啟用CNAME選項,即可實現自訂網域名訪問。

使用自訂網域名前,需確保已將自訂網域名綁定到Bucket。具體操作參見通過自訂網域名訪問OSS。

運行範例程式碼前,請將代碼中的 <region-id>預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
// 設定是否支援將自訂網域名作為Endpoint,預設不支援。
cname := oss.UseCname(true)

// 建立OSS用戶端執行個體
client, _ := oss.New(
	"http://example.com", // 自訂網域名
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("<region-id>"),
	cname,
)

逾時控制

初始化OSS用戶端時,使用oss.Timeout參數設定HTTP連線逾時時間和HTTP讀取或寫入逾時時間,單位為秒。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
// 設定HTTP連線逾時時間為20秒,HTTP讀取或寫入逾時時間為60秒
time := oss.Timeout(20, 60)

// 建立OSS用戶端執行個體
client, _ := oss.New(
	"<endpoint>",
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("<region-id>"),
	time,
)

設定串連池大小

初始化OSS用戶端時,通過oss.MaxConns參數調整串連池大小。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
// 設定最大閑置串連數MaxIdleConns為10,預設值為100
// 設定每個主機的最大閑置串連數MaxIdleConnsPerHost為20,預設值為100
// 設定每個主機的最大串連數MaxConnsPerHost為50,預設值為空白
conn := oss.MaxConns(10, 20, 50)

// 建立OSS用戶端執行個體
client, _ := oss.New(
	"<endpoint>",
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("<region-id>"),
	conn,
)

關閉CRC資料校正

可通過oss.EnableCRC(false)參數關閉CRC資料校正功能。

重要

強烈建議保持CRC資料校正功能開啟。關閉此功能後,OSS無法保證上傳和下載過程中資料的完整性。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
// 關閉CRC資料校正
crc := oss.EnableCRC(false)

// 建立OSS用戶端執行個體
client, _ := oss.New(
	"<endpoint>",
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("<region-id>"),
	crc,
)

簽名版本

重要

阿里雲Object Storage Service V1 簽名將按以下時間錶停止使用,建議儘快升級為V4簽名,確保服務不受影響。

  • 自 2025 年 3 月 1 日起,新註冊使用者無法使用 V1 簽名。

  • 自 2025 年 9 月 1 日起,逐步停止 V1 簽名的更新維護,且新建立的 Bucket 無法使用 V1 簽名。

以下範例程式碼採用V1簽名初始化用戶端。V4簽名用戶端初始化範例程式碼參見初始化用戶端。

運行範例程式碼前,請將代碼中的 endpoint預留位置替換為實際的地區和Endpoint,如 oss-ap-southeast-1.aliyuncs.com。
package main

// OSS Go SDK V1簽名版本初始化用戶端樣本

import (
	"fmt"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {

	// 從環境變數中載入訪問憑證(需要設定OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)
	provider, _ := oss.NewEnvironmentVariableCredentialsProvider()

	// 建立OSS用戶端執行個體
	client, _ := oss.New(
		"<endpoint>",
		"",
		"",
		oss.SetCredentialsProvider(&provider),
	)

	// 列舉所有Bucket
	buckets, err := client.ListBuckets()
	if err != nil {
		fmt.Printf("列舉Bucket失敗: %v\n", err)
		return
	}

	// 輸出Bucket列表資訊
	fmt.Printf("共找到 %d 個Bucket:\n", len(buckets.Buckets))

	for _, bucket := range buckets.Buckets {
		fmt.Printf("%s\n", bucket.Name)
	}
}

佈建要求上下文

通過請求上下文控制和管理請求的生命週期。

僅OSS Go SDK 2.2.9及以上版本支援佈建要求上下文。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
package main

// OSS Go SDK V1佈建要求上下文樣本

import (
	"context"
	"fmt"
	"time"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {

	// 從環境變數中載入訪問憑證(需要設定OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)
	provider, _ := oss.NewEnvironmentVariableCredentialsProvider()

	// 建立OSS用戶端執行個體
	client, _ := oss.New(
		"<endpoint>",
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("<region-id>"),
	)

	// 擷取Bucket對象
	bucket, _ := client.Bucket("example-bucket-hz")

	// 設定檔資訊
	key := "oss-browser2-mac-arm64-2.1.0.dmg"       // OSS中的檔案路徑
	file_path := "oss-browser2-mac-arm64-2.1.0.dmg" // 本地儲存路徑

	// 佈建要求上下文
	ctx := context.Background()

	// 指定請求上下文到期時間為5秒
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	// 將OSS中的檔案下載到本地指定路徑,並佈建要求上下文
	err := bucket.GetObjectToFile(key, file_path, oss.WithContext(ctx))
	if err != nil {
		select {
		case <-ctx.Done():
			fmt.Printf("請求取消或逾時: %v\n", err)
		default:
			fmt.Printf("下載失敗: %v\n", err)
		}
		return
	}

	fmt.Printf("檔案下載完成: %s -> %s\n", key, file_path)
}

異常處理

使用OSS Go SDK V1訪問OSS時出現錯誤,OSS會返回HTTP狀態代碼、錯誤訊息、請求ID以及EC錯誤碼等詳細資料。EC錯誤碼對應具體的錯誤原因,可用於快速定位和排查問題。例如下載不存在的對象檔案時,會返回以下錯誤資訊:

oss: service returned error: StatusCode=404, ErrorCode=NoSuchKey, ErrorMessage="The specified key does not exist.", RequestId=69030EDB2E5F223030953167, Ec=0026-00000001

錯誤資訊中的'EC': '0026-00000001'為EC錯誤碼,通過該錯誤碼可尋找具體的問題原因和解決方案。

範例程式碼

OSS Go SDK V1提供豐富的範例程式碼,涵蓋儲存空間管理、檔案操作、許可權控制、加密傳輸等核心功能,便於參考或直接使用。範例程式碼包括以下內容:

Github範例程式碼

官網文檔範例程式碼

new_bucket.go

初始化Client

create_bucket.go

建立儲存空間(Go SDK V1)

bucket_acl.go

管理儲存空間的讀寫權限(Go SDK V1)

bucket_policy.go

授權策略

bucket_referer.go

防盜鏈(Go SDK V1)

bucket_lifecycle.go

生命週期

bucket_logging.go

訪問日誌

bucket_cors.go

跨域訪問

bucket_website.go

靜態網站託管(鏡像回源)(Go SDK V1)

bucket_encryption.go

服務端加密(Go SDK V1)

bucket_requestpayment.go

要求者付費模式(Go SDK V1)

bucket_inventory.go

儲存空間清單(Go SDK V1)

bucket_accessmonitor.go

訪問跟蹤(Go SDK V1)

bucket_metaquery.go

資料索引(Go SDK V1)

list_buckets.go

列舉儲存空間(Go SDK V1)

bucket_stat.go

擷取儲存空間的儲存容量(Go SDK V1)

bucket_tagging.go

儲存空間標籤(Go SDK V1)

put_object.go

上傳檔案,包括簡單上傳(Go SDK V1)、斷點續傳上傳(Go SDK V1)等

append_object.go

追加上傳

get_object.go

下載檔案,包括流式下載(Go SDK V1)、限定條件下載(Go SDK V1)等

delete_object.go

刪除檔案(Go SDK V1)

copy_object.go

拷貝檔案(Go SDK V1)

list_objects.go

列舉檔案(Go SDK V1)

archive.go

解凍檔案(Go SDK V1)

object_acl.go

管理檔案讀寫權限

sign_url.go

使用預簽名URL上傳(Go SDK V1)

object_tagging.go

對象標籤

select_object.go

查詢檔案(Go SDK V1)

object_meta.go

管理檔案中繼資料(Go SDK V1)

livechannel.go

LiveChannel管理(Go SDK V1)

查詢Endpoint資訊

OSS Go SDK V1支援查詢所有地區或指定地區對應的Endpoint資訊,包括外網訪問(IPv4)Endpoint、內網訪問(傳統網路或VPC網路)Endpoint和傳輸加速網域名稱(全地區上傳下載加速)Endpoint。

說明

Go SDK 2.2.8及以上版本支援查詢Endpoint資訊。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
package main

// OSS Go SDK V1查詢Endpoint資訊樣本

import (
	"fmt"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {

	fmt.Println("=== 查詢所有支援地區對應的Endpoint資訊 ===\n")

	// 從環境變數中載入訪問憑證(需要設定OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET)
	provider, _ := oss.NewEnvironmentVariableCredentialsProvider()

	// 建立OSS用戶端執行個體
	client, err := oss.New(
		"<endpoint>",
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("<region-id>"),
	)
	if err != nil {
		fmt.Printf("建立用戶端失敗: %v\n", err)
		return
	}

	// 查詢所有支援地區對應的Endpoint資訊
	result, err := client.DescribeRegions()
	if err != nil {
		fmt.Printf("查詢Endpoint資訊失敗: %v\n", err)
		return
	}

	// 遍曆所有地區資訊
	for _, region := range result.Regions {
		fmt.Printf("地區: %s\n", region.Region)
		fmt.Printf("  外網訪問(IPv4)Endpoint: %s\n", region.InternetEndpoint)
		fmt.Printf("  內網訪問(傳統網路或VPC網路)Endpoint: %s\n", region.InternalEndpoint)
		fmt.Printf("  傳輸加速網域名稱(全地區上傳下載加速)Endpoint: %s\n", region.AccelerateEndpoint)
		fmt.Println("--------------------------------------------------------------------------------")
	}

	// 輸出統計資訊
	fmt.Printf("\n共查詢到 %d 個地區的Endpoint資訊\n", len(result.Regions))
}

若需查詢指定地區的Endpoint資訊,在DescribeRegions方法中指定OSS專用地區ID即可。

result, err := client.DescribeRegions(oss.AddParam("regions", "oss-<region-id>"))

訪問憑證配置

OSS 支援多種憑證初始化方式,需根據認證和授權需求選擇合適的初始化方式。

單擊查看如何選擇訪問憑證

憑證提供者初始化方式

適用情境

是否需要提供前置的AK或STS Token

底層實現基於的憑證

憑證有效期間

憑證輪轉或重新整理方式

使用RAM使用者的AK

部署運行在安全、穩定且不易受外部攻擊的環境的應用程式,無需頻繁輪轉憑證就可以長期訪問雲端服務

是

AK

長期

手動輪轉

使用STS臨時訪問憑證

部署運行在不可信的環境的應用程式,希望能控制訪問的有效期間、許可權

是

STS Token

臨時

手動重新整理

使用RAMRoleARN

需要授權訪問雲端服務,例如跨阿里雲帳號訪問雲端服務的應用程式

是

STS Token

臨時

自動重新整理

使用ECSRAMRole

部署運行在阿里雲的ECS執行個體、ECI執行個體、Container ServiceKubernetes版的Worker節點中的應用程式

否

STS Token

臨時

自動重新整理

使用OIDCRoleARN

部署運行在阿里雲的Container ServiceKubernetes版的Worker節點中的不可信應用程式

否

STS Token

臨時

自動重新整理

使用Function Compute上下文中的Credentials

部署運行在阿里雲Function Compute中的應用程式的函數

否

STS Token

臨時

無需重新整理

使用CredentialsURI

需要通過外部系統擷取訪問憑證的應用程式

否

STS Token

臨時

自動重新整理

使用自動輪轉的AK

部署運行在面臨AK泄露風險的環境的應用程式,需要頻繁輪轉憑證才長期能訪問雲端服務

否

AK

長期

自動輪轉

使用自訂訪問憑證

如果以上憑證配置方式都不滿足要求時,您可以自訂擷取憑證的方式

自訂

自訂

自訂

自訂

使用RAM使用者的AK

適用於應用程式部署運行在安全、穩定且不易受外部攻擊的環境中,需要長期訪問OSS且無法頻繁輪轉憑證的情境。通過阿里雲主帳號或RAM使用者的AK(Access Key ID、Access Key Secret)初始化憑證提供者。該方式需要手動維護AK,存在安全性風險和維護複雜度增加的風險。

重要
  • 阿里雲帳號擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。推薦使用最小化授權的RAM使用者的AK。

  • 如需建立RAM使用者的AK,請直接存取建立AccessKey。RAM使用者的Access Key ID、Access Key Secret資訊僅在建立時顯示,如若遺忘請建立新的AK進行替換。

環境變數

  1. 使用RAM使用者AccessKey配置環境變數。

    Linux

    1. 在命令列介面執行以下命令,將環境變數設定追加到~/.bashrc 檔案中。

      echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc
      echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc
    2. 執行以下命令使變更生效。

      source ~/.bashrc
    3. 執行以下命令檢查環境變數是否生效。

      echo $OSS_ACCESS_KEY_ID
      echo $OSS_ACCESS_KEY_SECRET

    macOS

    1. 在終端中執行以下命令,查看預設Shell類型。

      echo $SHELL
    2. 根據預設Shell類型進行操作。

      Zsh

      1. 執行以下命令,將環境變數設定追加到 ~/.zshrc 檔案中。

        echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc
        echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc
      2. 執行以下命令使變更生效。

        source ~/.zshrc
      3. 執行以下命令檢查環境變數是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET

      Bash

      1. 執行以下命令,將環境變數設定追加到 ~/.bash_profile 檔案中。

        echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile
        echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile
      2. 執行以下命令使變更生效。

        source ~/.bash_profile
      3. 執行以下命令檢查環境變數是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET

    Windows

    CMD

    1. 在CMD中運行以下命令。

      setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID"
      setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"
    2. 運行以下命令,檢查環境變數是否生效。

      echo %OSS_ACCESS_KEY_ID%
      echo %OSS_ACCESS_KEY_SECRET%

    PowerShell

    1. 在PowerShell中運行以下命令。

      [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User)
      [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
    2. 運行以下命令,檢查環境變數是否生效。

      [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User)
      [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
  2. 參考上述方式修改系統內容變數後,需重啟或重新整理編譯運行環境,包括IDE、命令列介面、其他傳統型應用程式及後台服務,以確保最新的系統內容變數成功載入。

  3. 使用環境變數傳遞憑證資訊。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    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
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    }

靜態憑證

通過在代碼中使用變數引用憑證,避免在源碼中寫入程式碼敏感資訊,這些變數在運行時從環境變數、設定檔或其他外部資料源擷取實際憑證值,提升代碼安全性和可維護性。設定檔實現方式如下:

  1. 安裝go-ini庫。

    go get -u github.com/go-ini/ini
  2. 建立設定檔config.ini。

    [credentials]
    alibaba_cloud_access_key_id = <ALIBABA_CLOUD_ACCESS_KEY_ID>
    alibaba_cloud_access_key_secret = <ALIBABA_CLOUD_ACCESS_KEY_SECRET>
  3. 編寫代碼從設定檔讀取憑證資訊並初始化OSS用戶端。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    	"gopkg.in/ini.v1"
    )
    
    type defaultCredentials struct {
    	config *oss.Config
    }
    
    func (defCre *defaultCredentials) GetAccessKeyID() string {
    	return defCre.config.AccessKeyID
    }
    
    func (defCre *defaultCredentials) GetAccessKeySecret() string {
    	return defCre.config.AccessKeySecret
    }
    
    func (defCre *defaultCredentials) GetSecurityToken() string {
    	return defCre.config.SecurityToken
    }
    
    type defaultCredentialsProvider struct {
    	config *oss.Config
    }
    
    func (defBuild *defaultCredentialsProvider) GetCredentials() oss.Credentials {
    	return &defaultCredentials{config: defBuild.config}
    }
    func NewDefaultCredentialsProvider(accessID, accessKey, token string) (defaultCredentialsProvider, error) {
    	var provider defaultCredentialsProvider
    	if accessID == "" {
    		return provider, fmt.Errorf("access key id is empty!")
    	}
    	if accessKey == "" {
    		return provider, fmt.Errorf("access key secret is empty!")
    	}
    	config := &oss.Config{
    		AccessKeyID:     accessID,
    		AccessKeySecret: accessKey,
    		SecurityToken:   token,
    	}
    	return defaultCredentialsProvider{
    		config,
    	}, nil
    }
    
    func main() {
    	cfg, err := ini.Load("config.ini")
    	if err != nil {
    		fmt.Println("Error loading config file:", err)
    		return
    	}
    	accessKeyID := cfg.Section("credentials").Key("alibaba_cloud_access_key_id").String()
    	accessKeySecret := cfg.Section("credentials").Key("alibaba_cloud_access_key_secret").String()
    	provider, err := NewDefaultCredentialsProvider(accessKeyID, accessKeySecret, "")
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	// yourEndpoint填寫Bucket對應的Endpoint
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    }

使用STS臨時訪問憑證

適用於應用程式需要臨時訪問OSS的情境。通過STS服務擷取的臨時身份憑證(Access Key ID、Access Key Secret和Security Token)初始化憑證提供者。該方式需要手動維護STS Token,存在安全性風險和維護複雜度增加的風險。如果需要多次臨時訪問OSS,需要手動重新整理STS Token。

重要
  1. 使用臨時身份憑證設定環境變數。

    Mac OS/Linux/Unix

    重要
    • 請注意,此處使用的是通過STS服務擷取的臨時身份憑證(Access Key ID、Access Key Secret和Security Token),而非RAM使用者的Access Key和Access Key Secret。

    • 請注意區分STS服務擷取的Access Key ID以STS開頭,例如“STS.****************”。

    export OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID>
    export OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET>
    export OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>

    Windows

    重要
    • 請注意,此處使用的是通過STS服務擷取的臨時身份憑證(Access Key ID、Access Key Secret和Security Token),而非RAM使用者的AK(Access Key ID、Access Key Secret)。

    • 請注意區分STS服務擷取的Access Key ID以STS開頭,例如“STS.****************”。

    set OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID>
    set OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET>
    set OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>
  2. 通過環境變數傳遞憑證資訊。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    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
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    }

使用RAMRoleARN

適用於應用程式需要授權訪問OSS,例如跨阿里雲帳號訪問OSS的情境。通過指定RAM角色的ARN(Alibabacloud Resource Name)初始化憑證提供者,底層實現基於STS Token。Credentials工具會前往STS服務擷取STS Token,並在會話到期前調用AssumeRole介面申請新的STS Token。還可以通過為policy賦值來限制RAM角色到一個更小的許可權集合。

重要
  • 阿里雲帳號擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。推薦使用最小化授權的RAM使用者的AK。

  • 如需建立RAM使用者的AK,請直接存取建立AccessKey。RAM使用者的Access Key ID、Access Key Secret資訊僅在建立時顯示,請及時儲存,如若遺忘請建立新的AK進行輪換。

  • 如需擷取RAMRoleARN,請直接存取建立角色。

  1. 添加credentials依賴。

    go get github.com/aliyun/credentials-go/credentials
  2. 配置AK和RAMRoleARN作為訪問憑證。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    	"github.com/aliyun/credentials-go/credentials"
    )
    
    type Credentials struct {
    	AccessKeyId     string
    	AccessKeySecret string
    	SecurityToken   string
    }
    
    type defaultCredentialsProvider struct {
    	cred credentials.Credential
    }
    
    func (credentials *Credentials) GetAccessKeyID() string {
    	return credentials.AccessKeyId
    }
    
    func (credentials *Credentials) GetAccessKeySecret() string {
    	return credentials.AccessKeySecret
    }
    
    func (credentials *Credentials) GetSecurityToken() string {
    	return credentials.SecurityToken
    }
    
    func (defBuild *defaultCredentialsProvider) GetCredentials() oss.Credentials {
    	cred, _ := defBuild.cred.GetCredential()
    	return &Credentials{
    		AccessKeyId:     *cred.AccessKeyId,
    		AccessKeySecret: *cred.AccessKeySecret,
    		SecurityToken:   *cred.SecurityToken,
    	}
    }
    
    func NewRamRoleArnCredentialsProvider(credential credentials.Credential) defaultCredentialsProvider {
    	return defaultCredentialsProvider{
    		cred: credential,
    	}
    }
    
    func main() {
    	config := new(credentials.Config).
    		// 填寫Credential類型,固定值為ram_role_arn。
    		SetType("ram_role_arn").
    		// 從環境變數中擷取RAM使用者的存取金鑰(AccessKeyId和AccessKeySecret)。
    		SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
    		SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")).
    		// 以下操作預設直接填入參數數值,您也可以通過添加環境變數,並使用os.Getenv("<變數名稱>")的方式來set對應參數
    		// 從環境變數中擷取RAM角色的ARN資訊,即需要扮演的角色ID。格式為acs:ram::$accountID:role/$roleName。
    		SetRoleArn("ALIBABA_CLOUD_ROLE_ARN"). // RoleArn預設環境變數正式名稱ALIBABA_CLOUD_ROLE_ARN
    		// 自訂角色會話名稱,用於區分不同的令牌。
    		SetRoleSessionName("ALIBABA_CLOUD_ROLE_SESSION_NAME"). // RoleSessionName預設環境變數正式名稱ALIBABA_CLOUD_ROLE_SESSION_NAME
    		// (可選)限制STS Token許可權。
    		SetPolicy("").
    		// (可選)限制STS Token的有效時間。
    		SetRoleSessionExpiration(3600)
    
    	arnCredential, err := credentials.NewCredential(config)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    
    	provider := NewRamRoleArnCredentialsProvider(arnCredential)
    	// yourEndpoint填寫Bucket對應的Endpoint
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    
    	fmt.Printf("client:%#v\n", client)
    }

使用ECSRAMRole

適用於應用程式運行在ECS執行個體、ECI執行個體、Container ServiceKubernetes版的Worker節點中的情境。建議使用ECSRAMRole初始化憑證提供者,底層實現基於STS Token。ECSRAMRole允許將一個角色關聯到ECS執行個體、ECI執行個體或Container Service Kubernetes 版的Worker節點,實現在執行個體內部自動重新整理STS Token。該方式無需提供AK或STS Token,消除了手動維護AK或STS Token的風險。如何擷取ECSRAMRole,請參見建立角色。如何將一個角色關聯到ECS執行個體,請參見執行個體RAM角色。

  1. 添加credentials依賴。

    go get github.com/aliyun/credentials-go/credentials
  2. 配置ECSRAMRole作為訪問憑證。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    	"github.com/aliyun/credentials-go/credentials"
    )
    
    type Credentials struct {
    	AccessKeyId     string
    	AccessKeySecret string
    	SecurityToken   string
    }
    
    type CredentialsProvider struct {
    	cred credentials.Credential
    }
    
    func (credentials *Credentials) GetAccessKeyID() string {
    	return credentials.AccessKeyId
    }
    
    func (credentials *Credentials) GetAccessKeySecret() string {
    	return credentials.AccessKeySecret
    }
    
    func (credentials *Credentials) GetSecurityToken() string {
    	return credentials.SecurityToken
    }
    
    func (defBuild CredentialsProvider) GetCredentials() oss.Credentials {
    	cred, _ := defBuild.cred.GetCredential()
    	return &Credentials{
    		AccessKeyId:     *cred.AccessKeyId,
    		AccessKeySecret: *cred.AccessKeySecret,
    		SecurityToken:   *cred.SecurityToken,
    	}
    }
    
    func NewEcsCredentialsProvider(credential credentials.Credential) CredentialsProvider {
    	return CredentialsProvider{
    		cred: credential,
    	}
    }
    
    func main() {
    	config := new(credentials.Config).
    		// 指定Credential類型,固定值為ecs_ram_role。
    		SetType("ecs_ram_role").
    		// (可選項)指定角色名稱。如果不指定,OSS會自動擷取角色。強烈建議指定角色名稱,以降低請求次數。
    		SetRoleName("RoleName")
    
    	ecsCredential, err := credentials.NewCredential(config)
    	if err != nil {
    		return
    	}
    	provider := NewEcsCredentialsProvider(ecsCredential)
    	// yourEndpoint填寫Bucket對應的Endpoint
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    
    }

使用OIDCRoleARN

在Container ServiceKubernetes版中設定了Worker節點RAM角色後,對應節點內的Pod中的應用也可以像ECS上部署的應用一樣,通過中繼資料服務(Meta Data Server)擷取關聯角色的STS Token。但如果容器叢集上部署的是不可信的應用(比如部署客戶提交的應用,代碼也沒有開放),可能並不希望它們能通過中繼資料服務擷取Worker節點關聯執行個體RAM角色的STS Token。為了避免影響雲上資源的安全,同時又能讓這些不可信的應用安全地擷取所需的STS Token,實現應用層級的許可權最小化,可以使用RRSA(RAM Roles for Service Account)功能。該方式底層實現基於STS Token。阿里雲容器叢集會為不同的應用Pod建立和掛載相應的服務賬戶OIDC Token檔案,並將相關配置資訊注入到環境變數中,Credentials工具通過擷取環境變數的配置資訊,調用STS服務的AssumeRoleWithOIDC介面換取綁定角色的STS Token。該方式無需提供AK或STS Token,消除了手動維護AK或STS Token的風險。詳情請參見通過RRSA配置ServiceAccount的RAM許可權實現Pod許可權隔離。

  1. 添加credentials依賴。

    go get github.com/aliyun/credentials-go/credentials
  2. 配置OIDC的RAM角色作為訪問憑證。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    	"github.com/aliyun/credentials-go/credentials"
    )
    
    type Credentials struct {
    	AccessKeyId     string
    	AccessKeySecret string
    	SecurityToken   string
    }
    
    type CredentialsProvider struct {
    	cred credentials.Credential
    }
    
    func (credentials *Credentials) GetAccessKeyID() string {
    	return credentials.AccessKeyId
    }
    
    func (credentials *Credentials) GetAccessKeySecret() string {
    	return credentials.AccessKeySecret
    }
    
    func (credentials *Credentials) GetSecurityToken() string {
    	return credentials.SecurityToken
    }
    
    func (defBuild CredentialsProvider) GetCredentials() oss.Credentials {
    	cred, _ := defBuild.cred.GetCredential()
    	return &Credentials{
    		AccessKeyId:     *cred.AccessKeyId,
    		AccessKeySecret: *cred.AccessKeySecret,
    		SecurityToken:   *cred.SecurityToken,
    	}
    }
    
    func NewOIDCRoleARNCredentialsProvider(credential credentials.Credential) CredentialsProvider {
    	return CredentialsProvider{
    		cred: credential,
    	}
    }
    
    func main() {
    	config := new(credentials.Config).
    		// 指定 OIDC 令牌的檔案路徑,用於儲存 OIDC 令牌。
    		SetOIDCTokenFilePath(os.Getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE")).
    		// 以下操作預設直接填入參數數值,您也可以通過添加環境變數,並使用os.Getenv("<變數名稱>")的方式來set對應參數
    		// 指定Credential類型,固定值為oidc_role_arn。
    		SetType("oidc_role_arn").
    		// 指定 OIDC 提供者的 ARN(Amazon Resource Name),格式為 acs:ram::account-id:oidc-provider/provider-name。
    		SetOIDCProviderArn("acs:ram::113511544585****:oidc-provider/TestOidcProvider"). // OIDCProviderArn預設環境變數正式名稱ALIBABA_CLOUD_OIDC_PROVIDER_ARN
    		// 自訂角色會話名稱,用於區分不同的令牌。
    		SetRoleSessionName("role_session_name"). // RoleSessionName預設環境變數正式名稱ALIBABA_CLOUD_ROLE_SESSION_NAME
    		// 填寫角色的ARN資訊,即需要扮演的角色ID。格式為acs:ram::113511544585****:oidc-provider/TestOidcProvider
    		SetRoleArn("acs:ram::113511544585****:role/testoidc"). // RoleArn預設環境變數正式名稱ALIBABA_CLOUD_ROLE_ARN
    		// (可選)指定訪問角色時要使用的策略。
    		SetPolicy("").
    		SetSessionExpiration(3600)
    	oidcCredential, err := credentials.NewCredential(config)
    	if err != nil {
    		return
    	}
    	provider := NewOIDCRoleARNCredentialsProvider(oidcCredential)
    	// yourEndpoint填寫Bucket對應的Endpoint
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    }

使用Function Compute上下文中的Credentials

適用於應用程式的函數部署運行在Function Compute中的情境。可以使用Function Compute上下文中的Credentials初始化憑證提供者,底層實現基於STS Token。Function Compute根據函數配置的角色,通過扮演服務角色擷取一個STS Token,然後通過上下文中的參數Credentials將STS Token傳遞給應用程式。該STS Token的有效期間為36小時,且不支援修改。函數的最大執行時間為24小時,因此,執行函數過程中,STS Token不會到期,無需考慮重新整理問題。該方式無需提供AK或STS Token,消除了手動維護AK或STS Token的風險。如何授予Function Compute訪問OSS的許可權,請參見使用函數角色授予Function Compute訪問其他雲端服務的許可權。

  1. 添加Function Compute上下文依賴。

    go get github.com/aliyun/fc-runtime-go-sdk/fc
    go get github.com/aliyun/fc-runtime-go-sdk/fccontext
  2. 使用Function Compute上下文中的Credentials初始化憑證提供者。

    package main
    
    import (
    	"context"
    	"fmt"
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    	"github.com/aliyun/fc-runtime-go-sdk/fc"
    	"github.com/aliyun/fc-runtime-go-sdk/fccontext"
    )
    
    type GetObjectContext struct {
    	OutputRoute string `json:"outputRoute"`
    	OutputToken string `json:"outputToken"`
    	InputOssUrl string `json:"inputOssUrl"`
    }
    
    type StructEvent struct {
    	GetObjectContext GetObjectContext `json:"getObjectContext"`
    }
    
    func HandleRequest(ctx context.Context, event StructEvent) error {
    	endpoint := event.GetObjectContext.OutputRoute
    	fctx, _ := fccontext.FromContext(ctx)
    	client, err := oss.New(endpoint, fctx.Credentials.AccessKeyId, fctx.Credentials.AccessKeySecret, oss.SecurityToken(fctx.Credentials.SecurityToken))
    	if err != nil {
    		return fmt.Errorf("client new error: %v", err)
    	}
    	fmt.Printf("client:%#v\n", client)
    	return nil
    }
    
    func main() {
    	fc.Start(HandleRequest)
    }

使用CredentialsURI

適用於應用程式需要通過外部系統擷取阿里雲憑證,從而實現靈活的憑證管理和無密鑰訪問的情境。可以使用CredentialsURI初始化憑證提供者,底層實現基於STS Token。Credentials工具通過提供的URI擷取STS Token,完成憑證用戶端初始化。該方式無需提供AK或STS Token,消除了手動維護AK或STS Token的風險。

重要
  • CredentialsURI指擷取STS Token的伺服器位址。

  • 提供CredentialsURI響應的後端服務需要實現STS Token的自動重新整理邏輯,確保應用程式始終能擷取到有效憑證。

  1. 為了使Credentials工具正確解析和使用STS Token,URI必須遵循以下響應協議:

    • 響應狀態代碼:200

    • 響應體結構:

      {
          "Code": "Success",
          "AccessKeySecret": "AccessKeySecret",
          "AccessKeyId": "AccessKeyId",
          "Expiration": "2021-09-26T03:46:38Z",
          "SecurityToken": "SecurityToken"
      }
  2. 添加credentials依賴。

    go get github.com/aliyun/credentials-go/credentials
  3. 配置CredentialsURI作為訪問憑證。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    	"github.com/aliyun/credentials-go/credentials"
    )
    
    type Credentials struct {
    	AccessKeyId     string
    	AccessKeySecret string
    	SecurityToken   string
    }
    
    type CredentialsProvider struct {
    	cred credentials.Credential
    }
    
    func (credentials *Credentials) GetAccessKeyID() string {
    	return credentials.AccessKeyId
    }
    
    func (credentials *Credentials) GetAccessKeySecret() string {
    	return credentials.AccessKeySecret
    }
    
    func (credentials *Credentials) GetSecurityToken() string {
    	return credentials.SecurityToken
    }
    
    func (defBuild CredentialsProvider) GetCredentials() oss.Credentials {
    	cred, _ := defBuild.cred.GetCredential()
    	return &Credentials{
    		AccessKeyId:     *cred.AccessKeyId,
    		AccessKeySecret: *cred.AccessKeySecret,
    		SecurityToken:   *cred.SecurityToken,
    	}
    }
    
    func NewCredentialsUriCredentialsProvider(credential credentials.Credential) CredentialsProvider {
    	return CredentialsProvider{
    		cred: credential,
    	}
    }
    
    func main() {
    	config := new(credentials.Config).
    		// 指定Credential類型,固定值為credentials_uri。
    		SetType("credentials_uri").
    		// 指定 url 地址;您也可以通過設定環境變數,並使用"os.Getenv("<變數名稱>")的方式進行參數傳遞。
    		// URLCredential預設環境變數正式名稱ALIBABA_CLOUD_CREDENTIALS_URI
    		SetURLCredential("http://127.0.0.1")
    	uriCredential, err := credentials.NewCredential(config)
    	if err != nil {
    		return
    	}
    	provider := NewCredentialsUriCredentialsProvider(uriCredential)
    	// yourEndpoint填寫Bucket對應的Endpoint
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    }

使用自動輪轉的AK

適用於應用程式需要長期訪問OSS,但部署啟動並執行環境面臨AK泄露風險,需要頻繁手動輪轉(輪換)AK的情境。可以使用ClientKey初始化憑證提供者,底層實現基於AK。使用ClientKey後,Key Management Service(KMS)可以對託管的RAM使用者AK進行全自動的定期輪轉,將靜態RAM使用者AK動態化,從而降低AK泄漏的風險。除定期輪轉外,KMS還支援立即輪轉,在AK泄漏情況下快速更換AK。該方式無需手動維護AK,從而降低安全性風險和維護複雜度。如何擷取ClientKey,請參見建立應用存取點。

  1. 添加憑據用戶端依賴。

    go get -u github.com/aliyun/aliyun-secretsmanager-client-go
  2. 建立設定檔secretsmanager.properties。

    # 訪問憑據類型
    credentials_type=client_key
    
    # 讀取client key的解密密碼:支援從環境變數或者檔案讀取
    client_key_password_from_env_variable=#your client key private key password environment variable name#
    client_key_password_from_file_path=#your client key private key password file path#
    
    # Client Key私密金鑰檔案路徑
    client_key_private_key_path=#your client key private key file path#
    
    # 關聯的KMS服務地區
    cache_client_region_id=[{"regionId":"#regionId#"}]
  3. 使用設定檔傳遞憑證資訊。

    運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
    package main
    
    import (
    	"encoding/json"
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    	"github.com/aliyun/aliyun-secretsmanager-client-go/sdk"
    )
    
    type defaultCredentials struct {
    	config *oss.Config
    }
    
    func (defCre *defaultCredentials) GetAccessKeyID() string {
    	return defCre.config.AccessKeyID
    }
    
    func (defCre *defaultCredentials) GetAccessKeySecret() string {
    	return defCre.config.AccessKeySecret
    }
    
    func (defCre *defaultCredentials) GetSecurityToken() string {
    	return defCre.config.SecurityToken
    }
    
    type defaultCredentialsProvider struct {
    	config *oss.Config
    }
    
    func (defBuild *defaultCredentialsProvider) GetCredentials() oss.Credentials {
    	return &defaultCredentials{config: defBuild.config}
    }
    func NewDefaultCredentialsProvider(accessID, accessKey, token string) (defaultCredentialsProvider, error) {
    	var provider defaultCredentialsProvider
    	if accessID == "" {
    		return provider, fmt.Errorf("access key id is empty!")
    	}
    	if accessKey == "" {
    		return provider, fmt.Errorf("access key secret is empty!")
    	}
    	config := &oss.Config{
    		AccessKeyID:     accessID,
    		AccessKeySecret: accessKey,
    		SecurityToken:   token,
    	}
    	return defaultCredentialsProvider{
    		config,
    	}, nil
    }
    
    func main() {
    	client, err := sdk.NewClient()
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	secretInfo, err := client.GetSecretInfo("#secretName#")
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("SecretValue:%s\n", secretInfo.SecretValue)
    	var m map[string]string
    	err = json.Unmarshal([]byte(secretInfo.SecretValue), &m)
    	if err != nil {
    		fmt.Println("Error decoding JSON:", err)
    		os.Exit(-1)
    	}
    	accessKeyId := m["AccessKeyId"]
    	accessKeySecret := m["AccessKeySecret"]
    	provider, err := NewDefaultCredentialsProvider(accessKeyId, accessKeySecret, "")
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	// yourEndpoint填寫Bucket對應的Endpoint
    	// yourRegion填寫Bucket所在地區
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("<region-id>"))
    	// 設定簽名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	ossClient, err := oss.New("<endpoint>", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", ossClient)
    }

使用自訂訪問憑證

當以上憑證配置方式都不滿足要求時,可以通過實現Credential Providers介面的方式自訂憑證提供方式。需要注意,如果底層實現基於STS Token,需要提供憑證的更新支援。

運行範例程式碼前,請將代碼中的 <region-id>等預留位置替換為實際的地區和Endpoint,如 ap-southeast-1。
package main

import (
	"fmt"
	"os"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

type CustomerCredentialsProvider struct {
	config *oss.Config
}

func NewCustomerCredentialsProvider() CustomerCredentialsProvider {
	return CustomerCredentialsProvider{}
}

func (s CustomerCredentialsProvider) GetCredentials() oss.Credentials {
	// 返回長期憑證
	config := &oss.Config{
		AccessKeyID:     "id",
		AccessKeySecret: "secret",
	}
	return &CustomerCredentialsProvider{
		config,
	}
	// 返回臨時憑證
	//config := &oss.Config{
	//    AccessKeyID:     "id",
	//    AccessKeySecret: "secret",
	//    SecurityToken:   "token",
	//}
	//return &CustomerCredentialsProvider{
	//    config,
	//}
}

func (s *CustomerCredentialsProvider) GetAccessKeyID() string {
	return s.config.AccessKeyID
}

func (s *CustomerCredentialsProvider) GetAccessKeySecret() string {
	return s.config.AccessKeySecret
}

func (s *CustomerCredentialsProvider) GetSecurityToken() string {
	return s.config.SecurityToken
}

func main() {
	provider := NewCustomerCredentialsProvider()
	// yourEndpoint填寫Bucket對應的Endpoint
	// yourRegion填寫Bucket所在地區
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("<region-id>"))
	// 設定簽名版本
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("<endpoint>", "", "", clientOptions...)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	fmt.Printf("client:%#v\n", client)
}

常見問題

當使用SDK時遇到報錯AccessDenied該如何進行排查?

遇到AccessDenied錯誤通常是因為缺少相應的存取權限。排查步驟如下:

  1. 確認AccessKey ID和AccessKey Secret:確保使用了正確的AccessKey ID和AccessKey Secret。

  2. 檢查RAM使用者權限:確認RAM使用者是否擁有Bucket或Object相關操作許可權。

  3. 檢查Bucket Policy:如果錯誤資訊中提到"Access denied by bucket policy",表明訪問被Bucket Policy策略拒絕。

  4. 更多錯誤類型的查詢和存取控制方面的常見報錯排查方法,請參考異常處理。

相關文檔