JWT双Token认证方案
一、核心设计
双Token机制:
- AccessToken:短期(15分钟),前端localStorage存储,每次请求校验
- RefreshToken:长期(7天),后端HttpOnly Cookie + MySQL存储,仅刷新时校验
验证策略:
- AccessToken:Redis黑名单验证(被吊销的才记录)
- RefreshToken:MySQL白名单验证(有效的才记录)
二、核心流程
1. 登录流程
用户登录成功 → 生成双Token → AccessToken返回前端存入localStorage → RefreshToken存入MySQL并设置HttpOnly Cookie。
2. API请求流程
前端携带AccessToken → 后端解析JWT(验证签名和过期)→ 查询Redis黑名单 → 不在黑名单则放行 → 处理业务返回结果。
3. 刷新流程(关键)
前端收到401 → 调用刷新接口(Cookie自动携带RefreshToken)→ 后端从MySQL查询RefreshToken进行匹配验证 → 验证通过则:
- 生成新双Token
- 旧AccessToken加入Redis黑名单(15分钟TTL)
- 更新MySQL中的RefreshToken为新值
- 新RefreshToken设置到HttpOnly Cookie
- 返回新AccessToken给前端
重要:RefreshToken验证只查MySQL,不查Redis黑名单。
4. 登出流程
用户登出 → 当前AccessToken加入Redis黑名单 → 删除MySQL中的RefreshToken记录 → 清除HttpOnly Cookie。
5. 安全事件处理
密码修改等安全事件 → 删除MySQL中的RefreshToken记录 → 强制重新登录。
三、存储设计
Redis黑名单
只存储被吊销的AccessToken,键格式:blacklist:access_token:{token_hash},TTL 15分钟(与AccessToken有效期一致)。
MySQL白名单
user_tokens表存储有效的RefreshToken,每个用户一条记录(user_id唯一约束),验证时只查询此表。
四、验证逻辑
AccessToken验证(黑名单逻辑)
默认所有AccessToken都有效,除非在Redis黑名单中。验证顺序:1.JWT解析 → 2.查Redis黑名单。
RefreshToken验证(白名单逻辑)
默认所有RefreshToken都无效,除非在MySQL白名单中且匹配。验证时只查MySQL,不查Redis。
五、性能与安全
性能优化
- AccessToken高频验证:Redis内存操作
- RefreshToken低频验证:MySQL查询,15分钟一次,可接受
安全设计
- AccessToken:短期有效,泄露风险小,可加入黑名单立即吊销
- RefreshToken:HttpOnly Cookie防XSS,每次刷新后失效(MySQL更新)
- 无RefreshToken黑名单:简化设计,通过MySQL更新保证旧Token失效
六、运维管理
监控重点
- Redis:黑名单大小、内存使用
- MySQL:查询性能、连接数
- 业务:刷新频率、401错误率
数据清理
- Redis:自动过期,无需手动清理
- MySQL:定期清理过期记录(每天凌晨)
故障处理
- Redis故障:降级为仅JWT验证(牺牲吊销能力)
- MySQL故障:刷新功能不可用,需重新登录
七、方案优势
- 高性能:高频操作用Redis,低频操作用MySQL
- 高安全:双Token分离,HttpOnly Cookie防护
- 简化设计:无RefreshToken黑名单,通过MySQL更新保证安全
- 易管理:AccessToken黑名单自动清理,MySQL便于审计
核心要点:RefreshToken验证只查MySQL白名单,不查Redis黑名单;安全事件通过删除MySQL记录使RefreshToken失效。