Redis集群怎么配合JWT搞权限控制,实操和思路分享
- 问答
- 2026-01-14 16:47:18
- 1
这个问题的核心思路其实不复杂,就是把JWT的“状态”和“黑名单”交给Redis集群来管理,从而解决JWT本身无法主动失效的难题,下面我结合一个常见的后台管理系统场景,分享一下实操和思路。
为什么单靠JWT不够?需要Redis集群?
来源:JWT(JSON Web Token)标准本身的设计特点。 JWT最大的优点是无状态,服务端签发一个Token后,里面包含用户ID、角色、过期时间等信息,后续请求只要验证Token签名有效、没过期,就认为用户是合法的,这很省事,不需要在服务端保存会话。
但这也带来了一个棘手的问题:如何让一个还没过期的Token立刻失效? 比如用户点了“退出登录”,或者管理员封禁了一个用户,这个用户的Token按理说应该立刻作废,但JWT本身做不到,因为它一旦签发,在过期前始终是有效的。
这时候就需要一个“黑名单”机制,而Redis,特别是Redis集群,就是管理这个黑名单(或者说,是记录有效/无效Token状态)的绝佳选择,原因如下:
- 速度快:权限验证是高频操作,每次请求都要检查,Redis基于内存,速度极快。
- 有过期时间:Redis可以给存储的Key设置过期时间(TTL),这个过期时间可以和JWT本身的过期时间对齐,自动清理,防止垃圾数据堆积。
- 集群高可用:单机Redis有宕机风险,用Redis集群可以保证即使某台机器挂了,整个权限控制系统依然能正常工作,这对于线上环境至关重要。
实操方案:以“用户退出登录”和“权限变更”为例
来源:常见的Web应用安全实践。
假设我们有一个系统,用户有普通用户和管理员两种角色。
用户登录 用户用用户名密码登录后,后端验证成功。
- 生成JWT:后端生成一个JWT,Payload(负载)里包含例如:
{“userId”: 123, “role”: “admin”, “exp”: 过期时间戳}。 - 存入Redis:同时,后端需要向Redis集群执行一个操作,这里有两种主流思路:
- 思路A:白名单模式(更常用):将一个Key为
jwt:user:123或jwt:具体的Token字符串,Value为某个标识(如"valid")的记录存入Redis,并设置这个Key的过期时间与JWT的过期时间一致,这意味着,只有在Redis里能找到的Token,才是有效的Token。 - 思路B:黑名单模式:登录时什么都不存,只有当用户退出或被迫下线时,才将Token存入一个黑名单(例如Key为
jwt:blacklist:具体的Token),并设置过期时间。
- 思路A:白名单模式(更常用):将一个Key为
- 返回给前端:将JWT返回给前端,前端后续在请求头(如Authorization头)里带上。
权限验证(核心环节) 后端需要一个统一的拦截器(如Spring里的Interceptor或Filter)来处理每个API请求。
- 获取Token:从请求头中取出JWT。
- 基础验证:先进行JWT的基础验证,包括签名是否正确、是否过期,如果失败,直接返回401错误。
- Redis状态验证(关键步骤):
- 如果用白名单模式:拦截器去Redis集群里查询
jwt:user:123(根据Token解析出的userId)或者jwt:具体的Token是否存在,如果查不到,说明这个Token已经被主动注销了(用户已退出),即使JWT本身没过期,也返回401错误。 - 如果用黑名单模式:拦截器去Redis集群里查询
jwt:blacklist:具体的Token是否存在,如果存在,说明这个Token已经被拉黑了,返回401错误。
- 如果用白名单模式:拦截器去Redis集群里查询
- 角色/权限验证:如果Redis验证通过,再从JWT的Payload里取出用户角色(如“admin”),判断该角色是否有权限访问当前请求的API地址,普通用户不能访问
/admin/delete-user这样的接口,如果没有权限,返回403错误。
用户退出登录 用户点击退出。
- 前端:丢弃本地存储的JWT。
- 后端:
- 白名单模式:直接删除Redis中对应的Key,
DEL jwt:user:123,这样,即使用户手快,在删除前发出的请求到达服务端,也会因为Redis中查不到记录而被拒绝。 - 黑名单模式:将当前这个还在有效期内的Token字符串作为Key,存入Redis黑名单,并设置一个较短的过期时间(比如剩余5分钟有效期)。
- 白名单模式:直接删除Redis中对应的Key,
管理员修改用户权限 假设管理员将用户123从“管理员”降级为“普通用户”。
- 后端操作:在数据库中更新用户的角色。
- 处理已签发的Token:用户123之前拿到的那个写着
“role”: “admin”的JWT还有1小时才过期,在这1小时内,他理论上还能以管理员身份操作,这是绝对不能允许的。 - 解决方案:在修改用户角色成功后,立即清除该用户在Redis中的状态,如果是白名单模式,就执行
DEL jwt:user:123,这样,用户123下一次携带旧Token请求时,Redis验证会失败,被迫重新登录,重新登录后就会拿到一个包含新角色(“user”)的新Token。
选择白名单还是黑名单?
- 白名单:更安全,控制力更强,可以实现“一处登录”或“限制登录设备数”,你可以在Redis里只允许一个用户ID存在一个有效的Token,新的登录会挤掉旧的,缺点是占用空间稍大,因为每个有效的Token都在Redis里有记录。
- 黑名单:更节省空间,因为只需要记录被注销的、尚未自然过期的少量Token,缺点是无法做“挤下线”这种精细控制,并且随着用户量增大,黑名单可能会变大(虽然有过期清理)。
对于大多数需要强安全控制的系统,我更推荐使用白名单模式,因为它能应对更多场景。
总结一下: JWT负责安全地携带用户身份信息,而Redis集群则负责给这个“无状态”的令牌增加一个“中心化”的开关,这个开关能让我们主动让令牌失效,实时响应权限变更,从而构建一个既高效又安全的权限控制系统,实操的关键在于,在用户登录、权限校验、退出登录、权限变更这几个关键节点,做好JWT和Redis的协同操作。

本文由盘雅霜于2026-01-14发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/80655.html
