OSS Go SDK V1

推荐使用新发布的OSS Go SDK V2alibabacloud-oss-go-sdk-v2),相较V1版本(aliyun-oss-go-sdk)在架构设计上进行了重大优化,简化了身份验证、请求重试、错误处理等底层操作逻辑,提供更灵活的参数配置方式和丰富的高级接口(如分页器、传输管理器、File-like接口等),显著提升开发效率和使用体验。从V1升级到V2,请参见Go SDK V1V2迁移指南

快速接入

通过以下步骤快速接入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)

初始化客户端

以下示例代码使用华东1(杭州)地域的外网访问域名初始化客户端,并列举当前账号下的Bucket列表进行验证。完整的地域和Endpoint列表请参见地域和Endpoint

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(
		"oss-cn-hangzhou.aliyuncs.com", // 以华东1(杭州)的外网访问Endpoint为例
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("cn-hangzhou"),
	)

	// 列举所有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

设置HTTPUser-Agent头,默认值为aliyun-sdk-go。

oss.UserAgent

ProxyHost

代理服务器主机地址和端口开关。取值如下:

  • true:开启代理服务器主机地址和端口。

  • false(默认值):关闭代理服务器主机地址和端口。

oss.AuthProxy

ProxyUser

代理服务器验证的用户名。

oss.AuthProxy

ProxyPassword

代理服务器验证的密码。

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指定为内网访问域名即可实现内网访问。

// 创建OSS客户端实例
client, _ := oss.New(
	"oss-cn-hangzhou-internal.aliyuncs.com", // 以华东1(杭州)的内网访问Endpoint为例
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("cn-hangzhou"),
)

使用自定义域名

Endpoint指定为自定义域名,并在初始化客户端时通过oss.UseCname(true)参数启用CNAME选项,即可实现自定义域名访问。

使用自定义域名前,需确保已将自定义域名绑定到Bucket。具体操作参见通过自定义域名访问OSS
// 设置是否支持将自定义域名作为Endpoint,默认不支持。
cname := oss.UseCname(true)

// 创建OSS客户端实例
client, _ := oss.New(
	"http://kitkat-cloud.cn", // 自定义域名
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("cn-hangzhou"),
	cname,
)

超时控制

初始化OSS客户端时,使用oss.Timeout参数设置HTTP连接超时时间和HTTP读取或写入超时时间,单位为秒。

// 设置HTTP连接超时时间为20秒,HTTP读取或写入超时时间为60秒
time := oss.Timeout(20, 60)

// 创建OSS客户端实例
client, _ := oss.New(
	"oss-cn-hangzhou.aliyuncs.com", // 以华东1(杭州)的外网访问Endpoint为例
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("cn-hangzhou"),
	time,
)

设置连接池大小

初始化OSS客户端时,通过oss.MaxConns参数调整连接池大小。

// 设置最大闲置连接数MaxIdleConns为10,默认值为100
// 设置每个主机的最大闲置连接数MaxIdleConnsPerHost为20,默认值为100
// 设置每个主机的最大连接数MaxConnsPerHost为50,默认值为空
conn := oss.MaxConns(10, 20, 50)

// 创建OSS客户端实例
client, _ := oss.New(
	"oss-cn-hangzhou.aliyuncs.com", // 以华东1(杭州)的外网访问Endpoint为例
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("cn-hangzhou"),
	conn,
)

关闭CRC数据校验

可通过oss.EnableCRC(false)参数关闭CRC数据校验功能。

重要

强烈建议保持CRC数据校验功能开启。关闭此功能后,OSS无法保证上传和下载过程中数据的完整性。

// 关闭CRC数据校验
crc := oss.EnableCRC(false)

// 创建OSS客户端实例
client, _ := oss.New(
	"oss-cn-hangzhou.aliyuncs.com", // 以华东1(杭州)的外网访问Endpoint为例
	"",
	"",
	oss.SetCredentialsProvider(&provider),
	oss.AuthVersion(oss.AuthV4),
	oss.Region("cn-hangzhou"),
	crc,
)

签名版本

重要

阿里云对象存储 V1 签名将按以下时间表停止使用,建议尽快升级为V4签名,确保服务不受影响。

  • 自 2025 年 3 月 1 日起,新注册用户无法使用 V1 签名。

  • 自 2025 年 9 月 1 日起,逐步停止 V1 签名的更新维护,且新创建的 Bucket 无法使用 V1 签名。

以下示例代码采用V1签名初始化客户端。V4签名客户端初始化示例代码参见初始化客户端

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(
		"oss-cn-hangzhou.aliyuncs.com", // 以华东1(杭州)的外网访问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及以上版本支持设置请求上下文。
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(
		"oss-cn-hangzhou.aliyuncs.com", // 以华东1(杭州)的外网访问Endpoint为例
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("cn-hangzhou"),
	)

	// 获取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错误码,通过该错误码可查找具体的问题原因和解决方案。具体操作步骤如下:

  1. 打开OpenAPI问题自助诊断平台

  2. 在搜索框中输入EC错误码,单击诊断按钮,查看问题原因和对应的解决方案。

    image

示例代码

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信息。不支持查询无地域属性(中国内地)地域的Endpoint信息。

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(
		"oss-cn-hangzhou.aliyuncs.com", // 以华东1(杭州)的外网访问Endpoint为例
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("cn-hangzhou"),
	)
	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-cn-hangzhou"))

访问凭证配置

OSS 支持多种凭证初始化方式,需根据认证和授权需求选择合适的初始化方式。

单击查看如何选择访问凭证

凭证提供者初始化方式

适用场景

是否需要提供前置的AKSTS Token

底层实现基于的凭证

凭证有效期

凭证轮转或刷新方式

使用RAM用户的AK

部署运行在安全、稳定且不易受外部攻击的环境的应用程序,无需频繁轮转凭证就可以长期访问云服务

AK

长期

手动轮转

使用STS临时访问凭证

部署运行在不可信的环境的应用程序,希望能控制访问的有效期、权限

STS Token

临时

手动刷新

使用RAMRoleARN

需要授权访问云服务,例如跨阿里云账号访问云服务的应用程序

STS Token

临时

自动刷新

使用ECSRAMRole

部署运行在阿里云的ECS实例、ECI实例、容器服务Kubernetes版的Worker节点中的应用程序

STS Token

临时

自动刷新

使用OIDCRoleARN

部署运行在阿里云的容器服务Kubernetes版的Worker节点中的不可信应用程序

STS Token

临时

自动刷新

使用函数计算上下文中的Credentials

部署运行在阿里云函数计算中的应用程序的函数

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. 使用环境变量传递凭证信息。

    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    func main() {
    	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_IDOSS_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请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("yourEndpoint", "", "", 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客户端。

    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,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("yourEndpoint", "", "", 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 SecretSecurity Token)初始化凭证提供者。该方式需要手动维护STS Token,存在安全性风险和维护复杂度增加的风险。如果需要多次临时访问OSS,需要手动刷新STS Token。

重要
  1. 使用临时身份凭证设置环境变量。

    Mac OS/Linux/Unix

    重要
    • 请注意,此处使用的是通过STS服务获取的临时身份凭证(Access Key ID、Access Key SecretSecurity Token),而非RAM用户的Access KeyAccess Key Secret。

    • 请注意区分STS服务获取的Access Key IDSTS开头,例如“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 SecretSecurity Token),而非RAM用户的AK(Access Key ID、Access Key Secret)。

    • 请注意区分STS服务获取的Access Key IDSTS开头,例如“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. 通过环境变量传递凭证信息。

    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    func main() {
    	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_IDOSS_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请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("yourEndpoint", "", "", 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. 配置AKRAMRoleARN作为访问凭证。

    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用户的访问密钥(AccessKeyIdAccessKeySecret)。
    		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,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    
    	fmt.Printf("client:%#v\n", client)
    }

使用ECSRAMRole

适用于应用程序运行在ECS实例、ECI实例、容器服务Kubernetes版的Worker节点中的场景。建议使用ECSRAMRole初始化凭证提供者,底层实现基于STS Token。ECSRAMRole允许将一个角色关联到ECS实例、ECI实例或容器服务 Kubernetes 版的Worker节点,实现在实例内部自动刷新STS Token。该方式无需提供AKSTS Token,消除了手动维护AKSTS Token的风险。如何获取ECSRAMRole,请参见创建角色。如何将一个角色关联到ECS实例,请参见实例RAM角色

  1. 添加credentials依赖。

    go get github.com/aliyun/credentials-go/credentials
  2. 配置ECSRAMRole作为访问凭证。

    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,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    
    }

使用OIDCRoleARN

在容器服务Kubernetes版中设置了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。该方式无需提供AKSTS Token,消除了手动维护AKSTS Token的风险。详情请参见通过RRSA配置ServiceAccountRAM权限实现Pod权限隔离

  1. 添加credentials依赖。

    go get github.com/aliyun/credentials-go/credentials
  2. 配置OIDCRAM角色作为访问凭证。

    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,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    }

使用函数计算上下文中的Credentials

适用于应用程序的函数部署运行在函数计算中的场景。可以使用函数计算上下文中的Credentials初始化凭证提供者,底层实现基于STS Token。函数计算根据函数配置的角色,通过扮演服务角色获取一个STS Token,然后通过上下文中的参数CredentialsSTS Token传递给应用程序。该STS Token的有效期为36小时,且不支持修改。函数的最大执行时间为24小时,因此,执行函数过程中,STS Token不会过期,无需考虑刷新问题。该方式无需提供AKSTS Token,消除了手动维护AKSTS Token的风险。如何授予函数计算访问OSS的权限,请参见使用函数角色授予函数计算访问其他云服务的权限

  1. 添加函数计算上下文依赖。

    go get github.com/aliyun/fc-runtime-go-sdk/fc
    go get github.com/aliyun/fc-runtime-go-sdk/fccontext
  2. 使用函数计算上下文中的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,完成凭证客户端初始化。该方式无需提供AKSTS Token,消除了手动维护AKSTS 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作为访问凭证。

    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,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", client)
    }

使用自动轮转的AK

适用于应用程序需要长期访问OSS,但部署运行的环境面临AK泄露风险,需要频繁手动轮转(轮换)AK的场景。可以使用ClientKey初始化凭证提供者,底层实现基于AK。使用ClientKey后,密钥管理服务(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. 使用配置文件传递凭证信息。

    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,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
    	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
    	clientOptions = append(clientOptions, oss.Region("yourRegion"))
    	// 设置签名版本
    	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
    	ossClient, err := oss.New("yourEndpoint", "", "", clientOptions...)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	fmt.Printf("client:%#v\n", ossClient)
    }

使用自定义访问凭证

当以上凭证配置方式都不满足要求时,可以通过实现Credential Providers接口的方式自定义凭证提供方式。需要注意,如果底层实现基于STS Token,需要提供凭证的更新支持。

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,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// 设置签名版本
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	fmt.Printf("client:%#v\n", client)
}

常见问题

当使用SDK时遇到报错AccessDenied该如何进行排查?

遇到AccessDenied错误通常是因为缺少相应的访问权限。排查步骤如下:

  1. 确认AccessKey IDAccessKey Secret:确保使用了正确的AccessKey IDAccessKey Secret。

  2. 检查RAM用户权限:确认RAM用户是否拥有BucketObject相关操作权限。

  3. 检查Bucket Policy:如果错误信息中提到"Access denied by bucket policy",表明访问被Bucket Policy策略拒绝。

  4. 更多错误类型的查询和访问控制方面的常见报错排查方法,请参考异常处理

相关文档