Go 集成教程
本教程介绍如何使用 Go 语言通过 Authorization Code Flow 集成 Code Bird Cloud 进行用户认证。
前置条件
- Go 1.21 或更高版本
- 已在 Code Bird Cloud 管理后台创建 Traditional 类型的应用,并获取 Client ID 和 Client Secret
- 已配置 Redirect URI 为
http://localhost:8080/callback
安装依赖
bash
go get github.com/coreos/go-oidc/v3/oidc
go get golang.org/x/oauth2| 依赖包 | 说明 |
|---|---|
github.com/coreos/go-oidc/v3/oidc | Go 生态中最流行的 OIDC 库,支持自动发现、令牌验证 |
golang.org/x/oauth2 | Go 官方 OAuth2 库,配合 go-oidc 使用 |
完整代码示例
go
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2"
)
var (
oidcProvider *oidc.Provider
oauth2Config oauth2.Config
verifier *oidc.IDTokenVerifier
)
func main() {
ctx := context.Background()
var err error
oidcProvider, err = oidc.NewProvider(ctx, "https://your-domain.com")
if err != nil {
log.Fatalf("Failed to initialize OIDC provider: %v", err)
}
oauth2Config = oauth2.Config{
ClientID: os.Getenv("CLIENT_ID"),
ClientSecret: os.Getenv("CLIENT_SECRET"),
RedirectURL: "http://localhost:8080/callback",
Endpoint: oidcProvider.Endpoint(),
// 按需添加 scope:"phone" 获取手机号;"urn:codebird:scope:organizations" 获取组织列表;
// "urn:codebird:scope:organization_roles" 获取组织角色
Scopes: []string{oidc.ScopeOpenID, "profile", "email", "offline_access"},
}
verifier = oidcProvider.Verifier(&oidc.Config{ClientID: oauth2Config.ClientID})
http.HandleFunc("/login", handleLogin)
http.HandleFunc("/callback", handleCallback)
log.Println("Server running at http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleLogin(w http.ResponseWriter, r *http.Request) {
state := "random-state-string" // Use crypto/rand in production
http.Redirect(w, r, oauth2Config.AuthCodeURL(state), http.StatusFound)
}
func handleCallback(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
code := r.URL.Query().Get("code")
token, err := oauth2Config.Exchange(ctx, code)
if err != nil {
http.Error(w, fmt.Sprintf("Token exchange failed: %v", err), http.StatusInternalServerError)
return
}
rawIDToken, ok := token.Extra("id_token").(string)
if !ok {
http.Error(w, "Missing id_token", http.StatusInternalServerError)
return
}
idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil {
http.Error(w, fmt.Sprintf("ID token verification failed: %v", err), http.StatusInternalServerError)
return
}
var claims struct {
Sub string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
}
if err := idToken.Claims(&claims); err != nil {
http.Error(w, fmt.Sprintf("Failed to parse claims: %v", err), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]any{
"subject": claims.Sub,
"name": claims.Name,
"email": claims.Email,
"access_token": token.AccessToken,
"refresh_token": token.RefreshToken,
})
}代码说明
OIDC Provider 初始化
oidc.NewProvider() 会自动调用 Code Bird Cloud 的 /.well-known/openid-configuration 端点,获取授权端点、令牌端点等配置信息。oidcProvider.Endpoint() 将发现的端点传递给 oauth2.Config。
ID Token 验证器
oidcProvider.Verifier() 创建一个 ID Token 验证器,用于验证令牌签名(ES256)、受众(aud 包含 client_id)以及过期时间。
登录处理 handleLogin
生成 state 参数并重定向用户到 Code Bird Cloud 的授权端点。
生产环境提醒: 示例中
state使用了固定字符串,生产环境中应使用crypto/rand生成密码学安全的随机值,并将其存储到 Session 或 Cookie 中,在回调时进行验证。
回调处理 handleCallback
- 从回调 URL 中提取授权码
code - 调用
oauth2Config.Exchange()用授权码换取令牌 - 从令牌响应中提取
id_token并使用验证器验证 - 解析 ID Token 中的 Claims 获取用户信息
运行
bash
# 设置环境变量
export CLIENT_ID="your_client_id"
export CLIENT_SECRET="your_client_secret"
# 运行服务
go run main.go访问 http://localhost:8080/login 开始登录流程。
相关文档
- Authorization Code Flow 参考 -- 流程详解和参数说明
- 集成概览 -- 所有集成方式的总览
