2.7 KiB
2.7 KiB
5.1 用户认证(JWT)
:::tip 概述 认证采用 JWT 双令牌:短时效 access_token 用于常规请求,长时效 refresh_token 用于兑换刷新。登出与强制下线经 Token 黑名单缓存实现,黑名单 TTL 取令牌剩余有效期自然过期。 :::
双令牌模型
| 令牌 | 配置键 | 默认 | 用途 |
|---|---|---|---|
| access_token | jwt.accessTokenExpire | 7200 秒(2 小时) | 请求头 Authorization: Bearer <token> |
| refresh_token | jwt.refreshTokenExpire | 604800 秒(7 天) | 经 /api/oauth2/token 兑换新令牌对 |
载荷携带用户身份(userID/username/realname/tenantID)与独立 jti(令牌唯一标识,黑名单与在线登记的键)。
签发与解析(utility/jwt)
jwt.Sign(ctx, tokenType, userID, tenantID, username, realname) // 签发(区分 access/refresh 类型)
jwt.Parse(ctx, tokenStr) // 解析校验(签名/过期/签发者)
jwt.ExpireDuration(ctx, tokenType) // 有效期查询
配置项:jwt.secret(签名密钥,生产必须更换)、jwt.issuer(签发者,解析时校验)。
校验链路(JWT 中间件)
免登录路径(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 | 登出(拉黑当前会话) |