新增 cls 包,提供 CloudLiteSync JWT 令牌校验与集成支持;包含 CLSService 结构体及相关方法,支持本地和远程 Token 校验。更新 go.mod 和 go.sum 文件以引入 jwt 库,添加 README.md 文档说明集成步骤。

This commit is contained in:
corkine
2025-07-22 17:45:38 +08:00
commit e6726d8dfa
4 changed files with 158 additions and 0 deletions

45
README.md Normal file
View File

@ -0,0 +1,45 @@
# 令牌集成帮助
## 快速集成
1. 安装依赖:
```sh
go get -u git.mazhangjing.com/corkine/cls-client
```
2. 在代码中引用:
```go
import "git.mazhangjing.com/corkine/cls-client/cls"
```
CloudLiteSync 支持基于 JWTJSON Web Token的令牌鉴权机制适用于微服务、Serverless、API 网关等多种场景。每个令牌项目拥有独立的 RSA 公私钥对,支持灵活的权限与用途隔离。
```go
package main
import (
"fmt"
"git.mazhangjing.com/corkine/cls-client/cls"
)
func main() {
// 假设 publicKeyPEM、matchPurpose、remoteServer 已获取
service := cls.NewCLSService(publicKeyPEM, matchPurpose, remoteServer)
// 1. 使用 JWT Token 进行本地校验
claims, err := service.JwtAuth(tokenString)
if err != nil {
fmt.Println("JWT 校验失败:", err)
return
}
fmt.Println("用户信息:", claims.Username, claims.Role)
// 2. 使用 quickKey 远程换取并校验 Token
claims2, err := service.TokenAuth(quickKey)
if err != nil {
fmt.Println("Token 校验失败:", err)
return
}
fmt.Println("用户信息:", claims2.Username, claims2.Role)
}
```

106
cls.go Normal file
View File

@ -0,0 +1,106 @@
// Package cls 提供 CloudLiteSync JWT 令牌校验与集成支持。
package cls
import (
"crypto/rsa"
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"io"
"net/http"
"time"
"github.com/golang-jwt/jwt/v5"
)
// CLSService 提供 JWT 校验与远程令牌获取服务。
type CLSService struct {
// PublicKey 用于校验 JWT 的 RSA 公钥
PublicKey *rsa.PublicKey
// MatchPurpose 期望的 purpose 字段,用于用途隔离
MatchPurpose string
// RemoteServer 远程令牌服务地址
RemoteServer string
}
// NewCLSService 创建一个新的 CLSService 实例。
// publicKeyPEM 为 PEM 格式的 RSA 公钥matchPurpose 为用途标识remoteServer 为远程服务地址。
func NewCLSService(publicKeyPEM, matchPurpose, remoteServer string) *CLSService {
block, _ := pem.Decode([]byte(publicKeyPEM))
if block == nil {
panic("failed to parse PEM block")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
return &CLSService{
PublicKey: pub.(*rsa.PublicKey),
MatchPurpose: matchPurpose,
RemoteServer: remoteServer,
}
}
// JWTClaims 表示 JWT 令牌的自定义声明体。
type JWTClaims struct {
Username string `json:"username"` // 用户名
Role string `json:"role"` // 角色
Purpose string `json:"purpose"` // 用途标识
jwt.RegisteredClaims
}
// JwtAuth 使用 JWT Token 进行本地校验,返回用户声明信息。
// tokenString 为待校验的 JWT 字符串。
// 校验 purpose 字段与服务配置是否一致,并检查过期时间。
func (s *CLSService) JwtAuth(tokenString string) (*JWTClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
// 校验签名算法是否为 RSA
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return s.PublicKey, nil
})
if err != nil {
return nil, fmt.Errorf("failed to parse token: %w", err)
}
if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
if claims.Purpose != s.MatchPurpose {
return nil, fmt.Errorf("purpose mismatch")
}
if claims.ExpiresAt.Before(time.Now()) {
return nil, fmt.Errorf("token expired")
}
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}
// TokenAuth 通过 quickKey 从远程服务获取并校验 JWT Token返回用户声明信息。
// key 为远程服务分发的 quickKey。
func (s *CLSService) TokenAuth(key string) (*JWTClaims, error) {
url := fmt.Sprintf("%s/s/%s", s.RemoteServer, key)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("remote server returned status %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var tokenClaims struct {
Token string `json:"token"`
}
err = json.Unmarshal(body, &tokenClaims)
if err != nil || tokenClaims.Token == "" {
return nil, err
}
return s.JwtAuth(tokenClaims.Token)
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.mazhangjing.com/corkine/cls-client
go 1.24.4
require github.com/golang-jwt/jwt/v5 v5.2.3

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0=
github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=