Skip to content

Go Verifier SDK 集成教程

本文档说明如何在 Go 业务后端中使用官方 codebird-go-sdk 验证来自前端的 Access Token,并基于结构化 AuthContext 做鉴权。

目标读者:

  • Go API 服务工程师
  • 第三方后端开发工程师
  • 需要读取用户 / 组织 / 租户上下文的资源服务器

这个 SDK 负责什么

Go Verifier SDK 负责:

  • OIDC Discovery
  • JWKS 拉取与缓存
  • JWT 签名验证
  • 标准 OIDC claims 解析
  • Code Bird Cloud 组织 claims 解析
  • 结构化 AuthContext 输出

它不负责:

  • 发起用户登录
  • 主动申请用户 Token
  • 替第三方做框架级路由跳转

适用场景

  • React SPA 登录后调用 Go API
  • 其他前端框架调用 Go 资源服务
  • 需要读取 organization_idorganization_rolesorganization_is_admin
  • 需要从 token 中读取轻量用户身份

安装

bash
go get github.com/lshaofan/codebird-go-sdk@latest

版本策略见:

第 1 步:创建 Verifier

go
verifier, err := codebird.NewVerifier(codebird.Config{
    Issuer:   "https://auth.codebird.cloud",
    Audience: "https://api.example.com",
})
if err != nil {
    log.Fatalf("failed to create verifier: %v", err)
}

参数说明

参数含义最佳实践
Issuer认证中心地址与前端 CodeBirdProvider.endpoint 完全一致
Audience当前业务 API 的资源标识与前端 defaultResource 完全一致
JWKSTTLJWKS 缓存时间生产环境可按默认或结合网关策略调整
ClockSkew时钟偏移容忍窗口只有跨系统时钟偏差明显时才需要调大

最关键的一条:

text
Go Audience == React defaultResource

第 2 步:解析 Bearer Token

go
token, err := codebird.ParseBearerToken(r.Header.Get("Authorization"))
if err != nil {
    http.Error(w, "unauthorized", http.StatusUnauthorized)
    return
}

推荐先统一把这一步收在中间件或公共 helper 中,不要在每个 Handler 里散落一遍。

第 3 步:验证 Access Token

go
authCtx, err := verifier.VerifyAccessToken(r.Context(), token)
if err != nil {
    http.Error(w, "unauthorized", http.StatusUnauthorized)
    return
}

验证成功后,你会得到结构化的 AuthContext

第 4 步:读取 AuthContext

常用字段:

go
userID := authCtx.Subject
username := authCtx.Username
email := authCtx.Email
organizationID := authCtx.OrganizationID
organizationIDs := authCtx.OrganizationIDs
organizationRoles := authCtx.OrganizationRoles
organizationIsAdmin := authCtx.OrganizationIsAdmin

当前推荐理解方式

  • organization_id:当前登录上下文组织
  • organization_roles:角色字符串数组的结构化结果
  • organization_is_admin:当前组织管理员布尔值

管理员身份判断不要再自己猜:

  • 不要根据 organization_roles 中是否包含 admin 推断管理员身份
  • 请直接使用 organization_is_admin

第 5 步:做业务鉴权

当前推荐写法是基于 AuthContext 的 helper 做判断。

判断 audience

go
if !authCtx.HasAudience("https://api.example.com") {
    http.Error(w, "forbidden", http.StatusForbidden)
    return
}

判断组织归属

go
if !authCtx.HasOrganization("org_123") {
    http.Error(w, "forbidden", http.StatusForbidden)
    return
}

判断组织角色

go
if !authCtx.HasOrganizationRole("org_123", "admin") {
    http.Error(w, "forbidden", http.StatusForbidden)
    return
}

获取某个组织的角色列表

go
roles := authCtx.RolesForOrganization("org_123")

推荐的中间件模式

官方不绑定 Gin / Echo / Fiber,但推荐项目方自己封一层很薄的中间件。

Gin 示例

go
func AuthMiddleware(verifier *codebird.Verifier) gin.HandlerFunc {
    return func(c *gin.Context) {
        token, err := codebird.ParseBearerToken(c.GetHeader("Authorization"))
        if err != nil {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "unauthorized"})
            return
        }

        authCtx, err := verifier.VerifyAccessToken(c.Request.Context(), token)
        if err != nil {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "unauthorized"})
            return
        }

        c.Set("auth_ctx", authCtx)
        c.Next()
    }
}

然后在业务 Handler 中只做业务判断,不重复做签名验证。

轻量 claims 与实时上下文

这一步很关键。

Token claims 适合做什么

  • 判断当前请求携带的 token 是否有效
  • 读取轻量用户身份
  • 读取当前组织上下文
  • 读取组织角色

Token claims 不适合做什么

  • 判断用户是否仍属于某组织
  • 判断管理员标记是否刚被后台改动
  • 判断组织关系是否已经实时变更

这类场景请改用实时接口:

当前 Go SDK 也已经支持获取实时会话上下文,推荐搭配使用。

什么时候应该调用实时会话上下文

推荐在下面这些场景使用:

  • 页面需要渲染用户最新昵称、手机号、头像
  • 用户组织关系可能在使用中被管理员修改
  • 你需要“当前数据库状态”,而不是“登录时 claims 快照”
  • 你需要顶层 tenant.slug 来生成终端用户 URL

实时上下文里当前标准返回:

  • tenant.id
  • tenant.slug
  • tenant.name
  • organization.is_admin

前后端协同最佳实践

如果前端用 React SDK,推荐这样配合:

前端负责

  • 登录
  • callback
  • token 自动续期
  • getAccessToken()
  • getSessionContext()

Go 后端负责

  • ParseBearerToken()
  • VerifyAccessToken()
  • 基于 AuthContext 做接口鉴权
  • 需要最新数据库状态时,再调用实时会话上下文

这样职责最清晰,也最容易排查问题。

当前常见错误

错误 1:前端 defaultResource 与后端 Audience 不一致

表现通常是:

  • 后端 401
  • 前端重复续期
  • token aud 看起来不对

错误 2:把 claims 当作实时权限数据

这会导致:

  • 用户已被移出组织,但业务仍放行
  • 用户管理员状态已变化,但服务仍按旧状态处理

错误 3:后端自己手拆 organization_roles

不推荐。

SDK 已经提供结构化 AuthContext 和 helper,不需要再自己解析原始 claims。

联调清单

前后端联调时至少确认:

  • Issuer 与前端 endpoint 一致
  • Audience 与前端 defaultResource 一致
  • Bearer Token 确实来自 Code Bird Cloud
  • API 服务端时钟没有明显漂移
  • 对组织级判权使用 AuthContext helper,而不是字符串手拆

相关文档

Released under the MIT License.