基于 Redis 实现验证码登录

基于 Redis 实现验证码登录

一、我的理解

  • 基于 Session 实现验证码登录,集群环境下,多个 Tomcat 服务器 Session 共享。
  • 基于 Redis 实现验证码登录,实现集群环境下,更新用户登录信息。

二、操作步骤














三、AI 的理解

你的理解是正确的。你准确地抓住了两种方案的核心目的:

  1. 基于 Session 的方案:其核心挑战与解决方案都围绕着如何让多个 Tomcat 服务器共享 Session 数据,以解决集群环境下的登录状态不一致问题。
  2. 基于 Redis 的方案:这是一种更现代和主流的 Token 架构,它利用 Redis 作为集中式存储来保存用户的登录信息(如用户ID、昵称等),并通过拦截器在每次请求时验证和更新(刷新)登录信息的有效期。

下面我将为你详细解析这两种方案的实现原理和区别。

🧩 方案一:基于 Session 的验证码登录与集群共享

这种方案是传统 Web 应用登录方式的延伸,核心在于将原本存储在单个 Tomcat 内存中的 Session 数据,迁移到一个所有 Tomcat 都能访问的"中央仓库"中。

单机环境下的流程

在未部署集群时,流程非常简单:

  1. 用户请求获取验证码,服务器生成验证码后,使用 session.setAttribute("code", code) 将其存入当前 Tomcat 的内存中。
  2. 用户提交手机号和验证码进行登录,服务器从 session.getAttribute("code") 取出验证码进行比对。
  3. 校验通过后,将用户信息也存入 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 架构。这也是目前微服务和前后端分离项目中最常用的方式。

核心流程
  1. 登录认证

    • 用户提交手机号和验证码。
    • 服务端从 Redis 中校验验证码(Key 为手机号)。
    • 校验通过后,根据手机号查询或创建用户。
    • 服务端生成一个全局唯一的随机字符串作为 Token (例如使用 UUID)。
    • 将用户信息(如 ID、昵称等)转换为一个 Map,并以 Hash 结构存入 Redis,Key 为这个 Token(例如 login:token:{token}),同时设置一个过期时间(如 30 分钟)。
    • 将这个 Token 返回给前端(通常放在响应体或 Cookie 中)。
  2. 后续请求与登录信息更新

    • 前端在之后的每一次请求中,都在请求头(如 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 和拦截器实现了灵活的登录状态管理和自动续期。

相关推荐
成都渲染101云渲染666615 分钟前
如何在3ds Max中实现更快、更高质量的渲染
前端·javascript·人工智能
SRET4 小时前
Mineradio 沙盒隔离安装完全指南 | 一键安全运行 Electron 应用!!!
javascript·经验分享·安全·electron·aigc·音视频·ai编程
全栈前端老曹4 小时前
【MongoDB】安全与权限管理 —— 用户认证、角色权限、SSL 加密
前端·javascript·数据库·安全·mongodb·nosql·ssl
free358 小时前
作用域链与 Environment:变量查找、遮蔽和赋值怎么实现
javascript
YHL8 小时前
🤖 Agent 智能体开发实战 · 第一课:Tool Use —— 让大模型自动干活
前端·javascript·人工智能
HUMHSX9 小时前
Vue 组件通信核心知识点梳理
javascript·vue.js·ecmascript
风止何安啊10 小时前
🚦 前端并发请求 “交通管制”:别让你的接口堵成早高峰
前端·javascript·面试
熊猫钓鱼>_>10 小时前
2026 前端的三场底层革命:当 Vue、React Native 和 Three.js 同时去掉中间层
前端·javascript·vue.js·react native·架构·webgl·three.js
名字还没想好☜10 小时前
React useEffect 依赖数组踩坑:闭包陷阱与清理函数
前端·javascript·react.js·react·useeffect
摇滚侠10 小时前
Redis7 零基础到进阶 Linux 离线安装 Redis 09-10
数据库·redis·缓存