redis集群配合jwt搞登录认证,性能和安全一起上了个台阶
- 问答
- 2025-12-28 11:43:26
- 4
redis集群配合jwt搞登录认证,性能和安全一起上了个台阶
以前我们做用户登录,办法挺简单的,最老土的就是用session,用户一登录,我们就在服务器这边给他生成一个会话记录,存起来,然后给用户的浏览器发一个叫session id的条子,用户下次再来,拿着这个条子,我们就去存放session的地方查一下,看看对不对,对就让他访问,这个方法用了好多年,也挺好使,但有个大问题,就是扩展起来特别麻烦,你想啊,现在网站为了扛住很多人同时访问,都会弄好多台服务器,组成一个集群,如果用户第一次访问被分到了A服务器登录,生成了session存在A服务器上,下次再来的时候,万一负载均衡器把他分到了B服务器,B服务器上可没有他的session记录,这不就坏事了嘛,又得让他重新登录,用户体验很差。
为了解决这个问题,以前大家也想了不少招,比如搞个session粘滞,就是想办法让同一个用户老是跑到同一台服务器上去,但这又失去了负载均衡的一些好处,万一那台服务器挂了,所有连在上面的用户都得掉线,又比如搞个session复制,一台服务器生了session,马上复制给其他所有服务器,这服务器一多,网络通信的压力就巨大,搞得整个系统都慢吞吞的,再不然就用个统一的数据库存所有的session,比如MySQL,这下倒是解决了共享的问题,但数据库读写,特别是这种高频的读操作,比起直接读内存要慢太多了,容易成为整个系统的瓶颈,用户一多,登录验证这块就卡脖子。

后来,JWT,也就是JSON Web Token,开始流行起来了,这东西的思路就完全不一样了,它不再把用户状态存在服务器这边,而是把所有需要的信息,比如用户ID、角色、有效期什么的,直接打包加密成一个长长的字符串(就是Token),然后把这个字符串直接发给用户,用户以后每次请求,只需要在HTTP头里带上这个Token就行了,我们服务器收到Token,只要验证一下签名是不是对的(证明Token是我们自己发的,没被篡改),再看看过期了没有,就能直接取出里面的用户信息来用了,这样一来,服务器就轻松了,完全不用再去查什么存储,变成了“无状态”的,特别适合前面说的多台服务器的集群环境。
光用JWT也有它自己的烦心事,主要就是安全控制不够灵活,因为这个Token一旦发出去,在它过期之前,理论上都是有效的,万一这个Token被坏人偷走了,他就能一直冒充这个用户,直到Token过期,我们想中途把这个Token作废掉都很难,因为服务器不记录它呀,比如用户想主动退出登录,或者我们管理员发现某个账号有异常,想立刻把他踢下线,传统的JWT就有点束手无策。
这时候,Redis集群就该上场了,Redis是个什么东西呢?你可以把它理解成一个速度超级快的、放在内存里的“大字典”或者“缓存中心”,它的读写速度极快,比数据库快好几个数量级,我们把Redis也做成一个集群,这样它自己也能扩展,能存很多东西,而且保证高可用。

怎么把JWT和Redis集群结合起来,既享受JWT无状态的好处,又能解决它的安全问题呢?办法其实很巧妙,我们不是在JWT里存了用户信息和过期时间吗?当我们用户登录成功,生成JWT之后,我们多做一个动作:把这个JWT的唯一标识(比如一个随机的JTI)或者干脆把整个Token本身(如果不太长的话)作为key,存到Redis集群里去,同时设置一个和JWT过期时间一致的存活时间,在Redis里,这个key对应的value可以很简单,就存个“有效”标记,或者再存点额外的用户信息也行,但最关键的是建立这么一个对应关系。
这样一来,整个流程就变成了:
- 用户登录,系统生成JWT。
- 将JWT的关键信息写入Redis集群,并设置过期时间。
- 将JWT返回给用户。
- 用户携带JWT访问其他接口。
- 服务器先做JWT本身的常规验证(签名、过期),验证通过后,再多做一步:去Redis集群里查一下,这个JWT是不是还存在,如果存在,说明它是有效的、没有被提前废止的;如果Redis里已经没了(可能因为主动删除或过期),那即使JWT本身没到期,我们也认为它是无效的,拒绝请求。
你看,这么一结合,好处立刻就出来了:

性能上的台阶:主要的用户身份信息还是通过JWT直接解析获得的,这步非常快,几乎不耗时间,只有当需要加强安全控制时,才需要去访问一次Redis,而Redis是内存操作,速度极快,集群模式又能承载巨大的访问量,相比之前用数据库存session的方案,性能提升不是一点半点,完全能满足高并发场景,用户感觉不到任何卡顿。
安全上的台阶:这才是最大的提升,我们现在有了一个“中央名单”,如果想主动让某个Token失效(比如用户退出登录、修改密码、账号被封禁),非常简单,只需要去Redis集群里把对应的那个key删掉就行了,立刻,这个Token就失效了,这就给了我们极大的安全管理灵活性,解决了纯JWT最大的痛点,因为Redis有天然的过期淘汰机制,那些正常过期的Token也会被自动清理掉,不会一直占着地方。
有人说“redis集群配合jwt搞登录认证,性能和安全一起上了个台阶”,这句话是非常形象的,它相当于是取了两者的长处:用JWT实现了无状态扩展和快速验证,用Redis集群实现了高效的中心化状态管理和主动失效能力,它既避免了传统session的扩展性问题,又弥补了纯JWT在安全控制上的不足,确实是一种在实践中被证明非常有效且流行的架构方案,现在很多大型的互联网应用,特别是微服务架构下的应用,都在采用这种或者类似的方式来管理用户的认证状态。
本文由革姣丽于2025-12-28发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/70012.html
