全部產品
Search
文件中心

Object Storage Service:OSS Go SDK V1

更新時間:Jan 24, 2026

推薦使用新發布的OSS Go SDK V2alibabacloud-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. 更多錯誤類型的查詢和存取控制方面的常見報錯排查方法,請參考異常處理

相關文檔