fix(auth): 有状态 JWT + 统一响应格式,严格遵循设计方案

1. 有状态 JWT(Token 存 Redis):
   - 新增 token_store.go: Token 的 Redis 存取管理
     - echo:auth:token:{user_id} → Access Token (TTL = access_expire_min)
     - echo:auth:refresh:{user_id} → Refresh Token (TTL = refresh_expire_day)
   - 登录/注册时自动将 Token 存入 Redis(覆盖旧 Token,实现单设备登录)
   - JWT 中间件增加 Redis 有效性校验(TokenValidator 接口解耦)
   - 登出时从 Redis 删除 Token,使其立即失效
   - 刷新 Token 时校验 Redis 中的 Refresh Token

2. 统一成功响应为 "success" + 200:
   - 注册接口改用 ResponseOK(原 ResponseCreated/201)
   - 所有成功响应统一为 {"code": 0, "message": "success"}

3. API 文档同步更新:
   - frontend/auth.md: 登出说明改为 Redis 方案、注册响应统一
   - README.md: 移除 "created" 示例

已验证:登出后 Token 立即失效 ✓ 重新登录后新 Token 有效 ✓

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-02-28 16:57:46 +08:00
parent 5a65716d10
commit b607434c57
9 changed files with 203 additions and 42 deletions

View File

@@ -46,7 +46,7 @@ func (ctrl *AuthController) Register(c *gin.Context) {
return
}
utils.ResponseCreated(c, resp)
utils.ResponseOK(c, resp)
}
// Login 用户登录
@@ -82,11 +82,19 @@ func (ctrl *AuthController) Logout(c *gin.Context) {
funcName := "controller.auth_controller.Logout"
ctx := c.Request.Context()
userID, _ := middleware.GetCurrentUserID(c)
userID, ok := middleware.GetCurrentUserID(c)
if !ok {
utils.ResponseUnauthorized(c, "无法获取用户信息")
return
}
logs.Info(ctx, funcName, "用户登出", zap.Int64("user_id", userID))
// 当前为无状态 JWT登出由客户端删除 Token 实现
// 后续可扩展:将 Token 加入 Redis 黑名单
if err := ctrl.authService.Logout(ctx, userID); err != nil {
utils.ResponseError(c, "登出失败")
return
}
utils.ResponseOK(c, nil)
}