本文介绍如何在代码中集成 IDaaS Go SDK,获取 M2M 客户端令牌。
适用范围
已完成环境准备工作,相关配置参见「准备环境」。
安装 SDK
通过 go get 添加依赖:
go get github.com/cloud-idaas/idaas-go-core-sdkSDK 初始化
读取用户在环境准备阶段指定的配置文件,完成 IDaaS 配置的初始化。factory.Init() 会自动完成配置加载、校验和 Token 预热,无需手动调用 config.NewConfigReader()。
package main
import (
"fmt"
"log"
"github.com/cloud-idaas/idaas-go-core-sdk/factory"
)
func main() {
// 初始化工厂(自动加载配置、校验、预热 token)
// 不传参数时按默认优先级链加载配置文件:
// 1. 显式文件路径(作为参数传入)
// 2. 环境变量 CLOUD_IDAAS_CONFIG_PATH
// 3. 默认路径 ~/.cloud_idaas/client-config.json
err := factory.Init()
if err != nil {
log.Fatalf("初始化失败: %v", err)
}
fmt.Println("SDK 初始化成功")
}重要提示:
SDK 功能均依赖
factory.Init()初始化方法,因此初始化必须先完成,否则获取IDaaSCredentialProvider等均会报错,导致业务中断。初始化是幂等的 —— 已初始化时再次调用不会重建。如需用新配置重新初始化,请先调用
factory.Reset()。初始化会执行配置校验(Defaulting → Normalize → Validate),配置缺失或校验失败会直接报错,导致业务中断。
初始化末尾会尝试预热(获取配置文件中指定 scope 的 Access Token)。预热采用容错模式:预热失败仅记录 WARN 日志,不阻断启动,避免启动期网络抖动导致进程无法启动。预热失败后,首次调用
GetCredential()时会重新触发刷新。
获取 Access Token
获取 IDaaS credentialProvider,用于获取 Access Token:
// 获取凭证提供者(根据配置文件中的 authnMethod 自动分发到对应认证流程)
provider, err := factory.GetIDaaSCredentialProvider()
if err != nil {
log.Fatalf("获取凭证提供者失败: %v", err)
}Access Token 是 Bearer 类型,通过 credentialProvider 的
GetCredential()方法获取凭证,再通过GetAccessToken()获取令牌字符串:
// 获取凭证
cred, err := provider.GetCredential()
if err != nil {
log.Fatalf("获取凭证失败: %v", err)
}
// 获取 Bearer Access Token
accessToken := cred.GetAccessToken()scope 格式为 受众标识|权限标识,对应所要访问的 M2M 服务端应用的受众标识和权限标识。默认使用配置文件中指定的 scope,如需访问不同的 scope,请修改配置文件中的 scope 字段。
说明: Go SDK 的 provider.GetCredential() + cred.GetAccessToken() 等价于 Java SDK 的 credentialProvider.getBearerToken() 和 Python SDK 的 get_bearer_token(),均用于获取 Bearer 类型的 Access Token。
生产环境推荐: 在请求链路中优先使用 GetCredentialWithContext(ctx) 方法,该方法支持 context 取消与 deadline 传播,避免网络故障时长时间阻塞。GetCredential() 内部等价于 GetCredentialWithContext(context.Background())。
完整代码示例
package main
import (
"fmt"
"log"
"github.com/cloud-idaas/idaas-go-core-sdk/factory"
)
func main() {
// 初始化工厂(自动加载配置、校验、预热 token)
err := factory.Init()
if err != nil {
log.Fatalf("初始化失败: %v", err)
}
// 获取 IDaaS credentialProvider,获取配置文件中指定 scope 的 Access Token
provider, err := factory.GetIDaaSCredentialProvider()
if err != nil {
log.Fatalf("获取凭证提供者失败: %v", err)
}
// 获取 Bearer 类型的 Access Token
cred, err := provider.GetCredential()
if err != nil {
log.Fatalf("获取凭证失败: %v", err)
}
accessToken := cred.GetAccessToken()
fmt.Println("Access Token:", accessToken)
}令牌交换
令牌交换(RFC 8693)允许您将主体令牌交换为具有不同 scope 或 audience 的访问令牌,适用于令牌降权和服务间调用场景。
package main
import (
"fmt"
"log"
"github.com/cloud-idaas/idaas-go-core-sdk/factory"
"github.com/cloud-idaas/idaas-go-core-sdk/provider"
)
func main() {
// 初始化工厂(自动加载配置、校验、预热 token)
err := factory.Init()
if err != nil {
log.Fatalf("初始化失败: %v", err)
}
// 要交换的主体令牌
subjectToken := "your_subject_token_here"
// 获取令牌交换提供者(factory 内部从环境变量读取 client secret)
tokenExchangeProvider, err := factory.GetIDaaSTokenExchangeCredentialProvider()
if err != nil {
log.Fatalf("获取令牌交换提供者失败: %v", err)
}
// 执行令牌交换(使用 TokenExchangeRequest 结构体封装参数)
cred, err := tokenExchangeProvider.ExchangeToken(provider.TokenExchangeRequest{
SubjectToken: subjectToken,
// ActorToken: actorToken, // 可选,用于委托授权场景
// Scope: "target_scope", // 可选,指定目标 scope
})
if err != nil {
log.Fatalf("令牌交换失败: %v", err)
}
fmt.Println("Exchanged Access Token:", cred.GetAccessToken())
}令牌交换参数说明
provider.TokenExchangeRequest 结构体字段:
参数 | 类型 | 必填 | 描述 |
SubjectToken | string | 是 | 要交换的令牌。 |
SubjectTokenType | string | 否 | subject token 的类型,默认 |
ActorToken | string | 否 | 用于委托授权的 Actor 令牌。 |
ActorTokenType | string | 否 | actor token 的类型,设置 ActorToken 时默认 |
RequestedTokenType | string | 否 | 期望获得的令牌类型。 |
Scope | string | 否 | 请求的 scope,为空时使用 provider 绑定的 scope。 |