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
# 登出时加入黑名单
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/微信的"已在其他设备登录"):
# 登录时记录设备
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天),但需可撤销:
# 存储 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 无效或已轮换")
速率限制与安全防护
# 登录失败计数(防暴力破解)
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 从"完全不可控"变为"可控的无状态",在架构简洁性和业务需求间取得平衡。
到此这篇关于redis在jwt中作用小结的文章就介绍到这了,更多相关redis jwt作用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论