核心概念
本页解释 CyberGo JWT 的核心抽象与设计模型,帮助你建立整体认知。如需直接动手,请跳转 快速开始。
Processor——核心类型
Processor 是库的中心类型,通过 jwt.New(cfg) 创建。它封装了令牌签发、验证、刷新和吊销的全部逻辑,所有方法并发安全,可在多个 goroutine 间共享同一实例。
使用完毕后调用 Close() 安全清除密钥并释放资源:
<!-- check-code: skip -->
cfg := jwt.DefaultConfig()
cfg.SecretKey = "your-32-byte-secret-key-here-minimum"
processor, err := jwt.New(cfg)
if err != nil {
log.Fatal(err)
}
defer processor.Close()Processor 实现了 TokenManager 接口,便于依赖注入和测试替换。
令牌生命周期
一张令牌从签发到失效,经过以下环节:
签发 Create(claims) → 访问令牌(短期)
CreateRefresh(claims) → 刷新令牌(长期)
验证 Validate(token) → Claims(检查签名、过期、签发者、黑名单)
刷新 Refresh(refreshToken) → 新访问令牌
吊销 Revoke(token) → 加入黑名单
查询 IsRevoked(token) → bool每个环节都返回哨兵错误(如 ErrTokenExpired、ErrTokenRevoked),可通过 errors.Is() 精确匹配。详见 错误处理。
双层令牌模型
CyberGo JWT 采用访问令牌 + 刷新令牌的双层设计:
| 访问令牌 | 刷新令牌 | |
|---|---|---|
| 用途 | API 认证 | 换取新访问令牌 |
| 默认 TTL | 15 分钟 | 7 天 |
| 签发方法 | Create | CreateRefresh |
| 刷新方法 | — | Refresh |
为什么用两层? 访问令牌有效期短,即使泄露风险窗口也小;刷新令牌有效期长但只用于换取新访问令牌,不直接用于 API 认证。这种设计在安全性与用户体验之间取得平衡——用户不必频繁登录,访问令牌过期后可静默刷新。
轮换语义
Refresh 不会自动吊销刷新令牌。原始刷新令牌在过期或显式 Revoke 之前仍然有效。如需一次性使用(refresh token rotation),请在 Refresh 成功后手动 Revoke 旧刷新令牌。详见 令牌刷新与轮换。
Claims 结构
Claims 携带令牌中的用户身份数据。CyberGo JWT 提供两层结构:
RegisteredClaims(RFC 7519 标准声明,自动填充与校验):
| 字段 | claim | 说明 |
|---|---|---|
| Issuer | iss | 签发方标识 |
| Subject | sub | 主体标识(也用作限流键) |
| Audience | aud | 目标受众 |
| ExpiresAt | exp | 过期时间 |
| NotBefore | nbf | 生效时间 |
| IssuedAt | iat | 签发时间 |
| ID | jti | 唯一标识(黑名单键) |
| TokenType | token_type | access 或 refresh |
Claims(内置业务声明,嵌入 RegisteredClaims):
<!-- check-code: skip -->
type Claims struct {
UserID string // 用户 ID
Username string // 用户名
Role string // 角色
Permissions []string // 权限列表
Scopes []string // OAuth 作用域
SessionID string // 会话 ID
ClientID string // 客户端 ID
Extra map[string]any // 额外字段
RegisteredClaims // 标准声明(嵌入)
}所有字段都经过输入验证:字符串长度上限 256、数组上限 100、注入模式检测(XSS/SQLi 签名)。
CustomClaims 接口
当内置 Claims 无法满足业务需求时,实现 CustomClaims 接口定义自己的声明结构:
<!-- check-code: skip -->
type AppClaims struct {
UserID string `json:"user_id"`
TeamID string `json:"team_id"`
Roles []string `json:"roles,omitempty"`
jwt.RegisteredClaims
}
func (c *AppClaims) GetRegisteredClaims() *jwt.RegisteredClaims {
return &c.RegisteredClaims
}
func (c *AppClaims) Validate() error {
if c.UserID == "" {
return errors.New("user_id is required")
}
return nil
}自定义类型通过 ValidateInto 验证、RefreshInto 刷新——Processor 会解析令牌并填充你的结构体。详见 自定义 Claims。
Config 配置概览
Config 是 Processor 的统一配置入口。通过 DefaultConfig() 获取合理默认值后,只需设置密钥即可使用:
| 分组 | 字段 | 说明 |
|---|---|---|
| 签名 | SecretKey / SigningKey / VerificationKey / SigningMethod | HMAC 用 SecretKey,RSA/ECDSA 用 SigningKey |
| 令牌 | AccessTokenTTL / RefreshTokenTTL | 访问与刷新令牌有效期 |
| 校验 | Issuer / ExpectedAudience / RequireExpiration / ClockSkew | 签发者、受众、强制过期、时钟容忍 |
| 安全 | Blacklist / EnableRateLimit | 吊销存储与速率限制 |
| 扩展 | Clock | 时钟注入(测试用) |
扩展接口
CyberGo JWT 通过接口实现可扩展性:
| 接口 | 用途 |
|---|---|
TokenManager | Processor 实现的核心接口。可定义自己的小子集接口(只需 Create + Validate),实现依赖注入与解耦 |
BlacklistStore | 自定义黑名单后端(如 Redis),实现 Add / Contains / Close 三方法即可对接外部存储 |
RateLimitProvider | 自定义限流器,实现 Allow / Reset / Close 即可替换内置令牌桶 |
ClockProvider | 时钟注入。FixedClock 返回固定时间,在测试中精确控制令牌过期与刷新逻辑 |