# 5.1 用户认证(JWT) :::tip 概述 认证采用 JWT 双令牌:短时效 access_token 用于常规请求,长时效 refresh_token 用于兑换刷新。登出与强制下线经 Token 黑名单缓存实现,黑名单 TTL 取令牌剩余有效期自然过期。 ::: ## 双令牌模型 | 令牌 | 配置键 | 默认 | 用途 | |---|---|---|---| | access_token | jwt.accessTokenExpire | 7200 秒(2 小时) | 请求头 `Authorization: Bearer ` | | refresh_token | jwt.refreshTokenExpire | 604800 秒(7 天) | 经 `/api/oauth2/token` 兑换新令牌对 | 载荷携带用户身份(userID/username/realname/tenantID)与独立 jti(令牌唯一标识,黑名单与在线登记的键)。 ## 签发与解析(utility/jwt) ```go jwt.Sign(ctx, tokenType, userID, tenantID, username, realname) // 签发(区分 access/refresh 类型) jwt.Parse(ctx, tokenStr) // 解析校验(签名/过期/签发者) jwt.ExpireDuration(ctx, tokenType) // 有效期查询 ``` 配置项:`jwt.secret`(签名密钥,生产必须更换)、`jwt.issuer`(签发者,解析时校验)。 ## 校验链路(JWT 中间件) ```text 免登录路径(IsPublicRequest)→ 直接放行 ↓ 解析 Bearer Token → jwt.Parse 校验签名、过期、签发者 ↓ 黑名单查询(cache: token:blacklist:{jti})→ 命中即 401 ↓ IdentityLoader 加载角色与权限(结果缓存 300 秒) ↓ 写入 ctx:用户身份 + 令牌 jti/exp + 角色权限集 + 数据范围 ``` 任一环节失败 → 401 信封(未认证请求不产生操作日志)。 ## 黑名单语义 - 键值无意义(存在即黑名单),TTL = 令牌剩余有效期 + 缓冲 - 登出/强制下线时 access 与 refresh **同时拉黑**——防止登出后凭刷新令牌兑换新令牌重新上线 - TTL 到期键自然失效,无需清理任务 ## 降级行为 IdentityLoader 未注册或加载失败时,身份扩展为空集——非超管按最小权限收敛不放行(HasPerm 不通过),仅保留令牌内基础身份。这是 fail-safe:接线故障不会放开权限。 ## 前端配合 - 请求拦截器自动携带 `Authorization: Bearer` - 收到 401 时前端走刷新流程或跳登录页 - 多端登录并存(不互踢),在线用户页可强制指定会话下线 ## 相关接口 | 接口 | 说明 | |---|---| | POST /api/oauth2/token | 刷新令牌 / 密码模式兑换(公开) | | GET /api/oauth2/check/token | 校验令牌有效性 | | DELETE /api/oauth2/remove/:token | 撤销指定令牌(管理员强制下线) | | GET /api/logout | 登出(拉黑当前会话) | ## 下一步 → [5.2 认证与授权流程](/zh/core/auth-flow.html)