全部产品
Search
文档中心

对象存储 OSS:OSS Go SDK V1

更新时间:Jan 23, 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

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

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

运行示例代码前,请将代码中的 <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,
)

签名版本

重要

阿里云对象存储 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实例、容器服务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. 使用环境变量传递凭证信息。

    运行示例代码前,请将代码中的 <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实例、容器服务Kubernetes版的Worker节点中的场景。建议使用ECSRAMRole初始化凭证提供者,底层实现基于STS Token。ECSRAMRole允许将一个角色关联到ECS实例、ECI实例或容器服务 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

在容器服务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。该方式无需提供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)
    }

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

适用于应用程序的函数部署运行在函数计算中的场景。可以使用函数计算上下文中的Credentials初始化凭证提供者,底层实现基于STS Token。函数计算根据函数配置的角色,通过扮演服务角色获取一个STS Token,然后通过上下文中的参数Credentials将STS Token传递给应用程序。该STS Token的有效期为36小时,且不支持修改。函数的最大执行时间为24小时,因此,执行函数过程中,STS Token不会过期,无需考虑刷新问题。该方式无需提供AK或STS Token,消除了手动维护AK或STS 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,完成凭证客户端初始化。该方式无需提供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后,密钥管理服务(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. 更多错误类型的查询和访问控制方面的常见报错排查方法,请参考异常处理。

相关文档