- 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> |
||
|---|---|---|
| .. | ||
| jwt_test.go | ||
| jwt.go | ||
| race_test.go | ||
| 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
安全注意事项
- 密钥管理:生产环境必须从环境变量或密钥管理服务读取密钥
- HTTPS:Token必须通过HTTPS传输
- Token存储:Token存储在数据库中,支持单设备登录
- updated_at验证:修改密码后,
updated_at更新,旧Token自动失效
测试
运行测试:
go test ./pkg/jwt -v
测试覆盖:
- ✅ Token生成和解析
- ✅ Token过期验证
- ✅ Token签名验证
- ✅ 各种错误场景