topfans/backend/pkg/jwt
zerosaturation 293c7b14ae fix(security): JWT key governance — MustInit fail-fast + atomic.Value
- pkg/jwt: 删 public SetSecret; 加 MustInit(secret string) 启动时强制注入,
  缺/为空/等于弱默认值时返回 error(运行期不可再改); 密钥用 atomic.Value
  存 []byte,所有读走 mustSecret() 原子 Load,消除 SetSecret/ParseToken 并发
  data race(go test -race 零告警)。
- gateway main + auth_provider: 启动时 MustInit 读 JWT_SECRET env,失败 fatal。
- scripts/loadgen/seed/tokens: 同步 MustInit。
- .env.example: JWT_SECRET 改为 ≥32 字节 base64 示例(原为空,被 MustInit
  立即拒);注释提示生产 MUST replace。
- 测试: 4 个 MustInit 行为 + 1 个 50-goroutine race 覆盖。
- 行为变更: 任何 .env 缺 JWT_SECRET 或用占位 secret 的服务,启动会 panic
  (这是 fail-fast 期望行为);其余 4 个 .env 文件占位由 ops 单独轮换。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-23 18:50:12 +08:00
..
jwt_test.go fix(security): JWT key governance — MustInit fail-fast + atomic.Value 2026-07-23 18:50:12 +08:00
jwt.go fix(security): JWT key governance — MustInit fail-fast + atomic.Value 2026-07-23 18:50:12 +08:00
race_test.go fix(security): JWT key governance — MustInit fail-fast + atomic.Value 2026-07-23 18:50:12 +08:00
README.md

JWT 工具层

JWT Token生成、解析和验证工具包。

功能

  • JWT Token生成包含 user_id, star_id, updated_at, exp
  • JWT Token解析和验证签名验证、过期时间检查
  • Token过期时间工具函数

使用方法

1. 设置密钥(服务启动时调用)

import "github.com/topfans/backend/pkg/jwt"

// 从环境变量或配置文件读取密钥
secret := os.Getenv("JWT_SECRET")
jwt.SetSecret(secret)

2. 生成Token

userID := int64(10000001)
starID := int64(123)
updatedAt := time.Now().UnixMilli()

token, err := jwt.GenerateToken(userID, starID, updatedAt)
if err != nil {
    // 处理错误
}

3. 解析和验证Token

// 解析Token不验证过期时间用于刷新Token场景
claims, err := jwt.ParseToken(token)
if err != nil {
    // 处理错误
}

// 验证Token检查签名和过期时间
claims, err := jwt.ValidateToken(token)
if err != nil {
    // 处理错误
}

4. 获取Token中的信息

// 从Token中解析Claims获取star_id
claims, err := jwt.ValidateToken(token)
if err != nil {
    // 处理错误
}

starID := claims.StarID
userID := claims.UserID
updatedAt := claims.UpdatedAt

注意前端可以直接解析JWT的payload部分Base64解码来获取star_id等信息无需额外拼接。

JWT Claims结构

type Claims struct {
    UserID    int64 `json:"user_id"`
    StarID    int64 `json:"star_id"`
    UpdatedAt int64 `json:"updated_at"`
    Iat       int64 `json:"iat"`  // 签发时间
    Exp       int64 `json:"exp"`  // 过期时间
}

Token格式

  • JWT Token标准JWT格式包含签名
  • Claims内容user_id, star_id, updated_at, iat, exp
  • 前端使用直接使用JWT Token可以从Token中解析出star_id等信息

Token有效期

  • 默认有效期7天
  • 过期后需要调用刷新Token接口获取新Token

安全注意事项

  1. 密钥管理:生产环境必须从环境变量或密钥管理服务读取密钥
  2. HTTPSToken必须通过HTTPS传输
  3. Token存储Token存储在数据库中支持单设备登录
  4. updated_at验证:修改密码后,updated_at更新旧Token自动失效

测试

运行测试:

go test ./pkg/jwt -v

测试覆盖:

  • Token生成和解析
  • Token过期验证
  • Token签名验证
  • 各种错误场景