基于 Redis 实现验证码登录
基于 Redis 实现验证码登录一、我的理解基于 Session 实现验证码登录集群环境下多个 Tomcat 服务器 Session 共享。基于 Redis 实现验证码登录实现集群环境下更新用户登录信息。二、操作步骤三、AI 的理解你的理解是正确的。你准确地抓住了两种方案的核心目的基于 Session 的方案其核心挑战与解决方案都围绕着如何让多个 Tomcat 服务器共享 Session 数据以解决集群环境下的登录状态不一致问题。基于 Redis 的方案这是一种更现代和主流的 Token 架构它利用 Redis 作为集中式存储来保存用户的登录信息如用户ID、昵称等并通过拦截器在每次请求时验证和更新刷新登录信息的有效期。下面我将为你详细解析这两种方案的实现原理和区别。 方案一基于 Session 的验证码登录与集群共享这种方案是传统 Web 应用登录方式的延伸核心在于将原本存储在单个 Tomcat 内存中的 Session 数据迁移到一个所有 Tomcat 都能访问的“中央仓库”中。单机环境下的流程在未部署集群时流程非常简单用户请求获取验证码服务器生成验证码后使用session.setAttribute(code, code)将其存入当前 Tomcat 的内存中。用户提交手机号和验证码进行登录服务器从session.getAttribute(code)取出验证码进行比对。校验通过后将用户信息也存入 Session标记为登录状态。集群环境下的问题当部署了多个 Tomcat 服务器并由 Nginx 进行负载均衡时问题就出现了第一次请求用户被分配到Tomcat-1验证码存入了Tomcat-1的内存。第二次请求用户的登录请求被 Nginx 分发到了Tomcat-2。由于Tomcat-2的内存中没有之前保存的验证码导致校验失败。这就是所谓的Session 粘滞性问题。解决方案Redis 实现 Session 共享业界最主流的解决方案就是使用Redis 作为集中的 Session 存储器。改造点将所有session.setAttribute()和session.getAttribute()的操作替换为对 Redis 的读写操作。效果无论用户的请求被分发到哪一台 Tomcat它们都去同一个 Redis 服务器存取验证码和用户 Session 信息从而实现了 Session 的共享。✨ 方案二基于 Redis 的 Token 登录与信息更新这是一种更彻底的改造它完全抛弃了传统的 Servlet Session 机制采用了无状态的Token 架构。这也是目前微服务和前后端分离项目中最常用的方式。核心流程登录认证用户提交手机号和验证码。服务端从 Redis 中校验验证码Key 为手机号。校验通过后根据手机号查询或创建用户。服务端生成一个全局唯一的随机字符串作为Token(例如使用 UUID)。将用户信息如 ID、昵称等转换为一个 Map并以 Hash 结构存入 RedisKey 为这个 Token例如login:token:{token}同时设置一个过期时间如 30 分钟。将这个 Token 返回给前端通常放在响应体或 Cookie 中。后续请求与登录信息更新前端在之后的每一次请求中都在请求头如Authorization携带这个 Token。服务端通过一个拦截器 (Interceptor)拦截所有需要登录的请求。拦截器从请求头中获取 Token然后去 Redis 中查询对应的用户信息。如果查不到说明未登录或登录已过期直接返回 401 状态码。如果能查到则将用户信息保存到ThreadLocal中供本次请求的后续业务逻辑使用。关键一步更新登录信息。在放行请求前拦截器会调用redisTemplate.expire(key, time)方法刷新 Redis 中该 Token 键的过期时间。这就实现了你所说的“更新用户登录信息”即只要用户持续活跃登录状态就会自动续期。 两种方案对比对比维度基于 Session 的共享方案基于 Redis 的 Token 方案核心思想改造原有 Session使其存储于外部 Redis。完全放弃 Session采用无状态的 Token 机制。数据存储仍保留 Session 概念但数据在 Redis。无 Session用户数据以 Hash 形式存于 Redis。客户端凭证JSESSIONID (通过 Cookie 传递)。自定义 Token (通常在请求头传递)。适用场景传统服务端渲染项目改造。前后端分离、微服务、移动端 App。优点对原有代码侵入性相对较小。无状态、扩展性强、跨平台支持好。总而言之你的理解非常到位。第一种方案是为了解决 Session 在集群下的共享难题而第二种方案则是一种更优的实践它不仅解决了共享问题还通过 Token 和拦截器实现了灵活的登录状态管理和自动续期。