Redis 在上述认证流程中主要扮演状态管理者和性能加速器的角色,弥补了 JWT 无状态特性的不足。以下是具体作用:
核心作用:解决 JWT 的"不可撤销"问题
JWT 一旦签发,在过期前无法主动失效(这是无状态的双刃剑)。Redis 通过存储关键状态,实现了有状态的控制能力:
传统 JWT:签发 ──► 过期前一直有效(即使用户登出)
JWT + Redis:签发 ──► Redis 标记失效 ──► 即时作废
具体应用场景
- Token 黑名单(登出失效)
场景 实现方式 Redis 数据结构 用户主动登出 将 Token 的 jti(唯一ID)存入 Redis,设置过期时间为 Token 剩余有效期 SET blacklist:{jti} 1 EX {remaining_ttl} 后台强制下线 同上,或存储用户级标记 SET user:{id}:force_logout 1
python
# 登出时加入黑名单
def logout(token_jti, exp_timestamp):
ttl = exp_timestamp - current_time()
redis.setex(f"blacklist:{token_jti}", ttl, "revoked")
# 验证时检查
def is_token_valid(token_jti):
return not redis.exists(f"blacklist:{token_jti}")
- 多端登录控制
限制同一账号同时登录设备数(如 QQ/微信的"已在其他设备登录"):
python
# 登录时记录设备
redis.lpush(f"user:{user_id}:sessions", token_jti)
redis.ltrim(f"user:{user_id}:sessions", 0, 2) # 只保留最近3个
# 验证时检查当前 Token 是否在列表中
valid_tokens = redis.lrange(f"user:{user_id}:sessions", 0, -1)
if token_jti not in valid_tokens:
raise Exception("账号已在其他设备登录")
- Refresh Token 存储
Access Token 短期有效(15分钟),Refresh Token 长期有效(7天),但需可撤销:
python
# 存储 Refresh Token 与用户绑定
redis.setex(
f"refresh:{user_id}:{device_id}",
7*24*3600, # 7天过期
hash(refresh_token) # 存储哈希值防泄露
)
# 刷新时验证
stored_hash = redis.get(f"refresh:{user_id}:{device_id}")
if stored_hash != hash(incoming_refresh_token):
raise Exception("Refresh Token 无效或已轮换")
- 速率限制与安全防护
python
# 登录失败计数(防暴力破解)
key = f"login_attempts:{ip}"
attempts = redis.incr(key)
if attempts == 1:
redis.expire(key, 3600) # 1小时窗口
if attempts > 5:
raise Exception("尝试次数过多,请稍后再试")
# Token 使用频率限制(防 Token 泄露后被滥用)
redis.zadd(f"token:{jti}:requests", {current_time(): current_time()})
# 清理1分钟前的记录
redis.zremrangebyscore(f"token:{jti}:requests", 0, current_time()-60)
if redis.zcard(f"token:{jti}:requests") > 100:
# 1分钟内请求超过100次,可能泄露,加入黑名单
redis.setex(f"blacklist:{jti}", 3600, "suspected_leak")
架构对比
方案 优点 缺点 适用场景 纯 JWT 完全无状态,扩展性强 无法强制失效,难以追踪 内部服务、短期令牌 JWT + Redis 黑名单 可撤销,保留无状态优势 每次验证需查 Redis 常规 Web 应用 纯 Redis Session 完全可控,可实时强制下线 有状态,扩展需共享 Session 高安全要求(金融)
关键设计原则
- 最小化存储:Redis 只存必要的状态标记(如黑名单),不存完整的用户数据
- TTL 对齐:Redis 键的过期时间严格对齐 JWT 的
exp时间,避免永久堆积 - 异步清理:黑名单过期后自动删除,无需人工维护
本质:Redis 让 JWT 从"完全不可控"变为"可控的无状态",在架构简洁性和业务需求间取得平衡。