这篇文章标题为 “黑马点评项目‑短信登录功能”,分享的是一个基于 Spring Boot + Vue 构建的「点评系统」中短信验证码登录模块的完整实现流程,涵盖从前端部署到后端逻辑和 Redis 集群设计。以下是详细解析 🛠️:
一、项目环境准备
- 前端通过 Nginx(Mac 本地或虚拟机)部署,替换配置并开放端口,第 3.1–3.5 节详述部署系列步骤 (blog.csdn.net)。
- 操作包括:替换
nginx.conf
配置、上传前端资源、启动服务,并保证跨虚拟机/宿主可访问。
二、短信登录功能设计
✉️1. 发送验证码(UserController + UserService)
- 客户端请求
/user/code?phone=xxx
; -
后端通过
UserService.sendCode()
:- 验证手机号格式;
- 用
RandomUtil.randomNumbers(6)
生成 6 位验证码; - 把验证码存入
session
,之后会拓展到 Redis(blog.csdn.net)。
🔑2. 登录与注册逻辑
-
/user/login
接口处理phone
和code
; - 从 session(或 Redis)中获取验证码,比对后验证通过;
-
账号存在? 用 MyBatis‑Plus 查询:
query().eq("phone", phone).one()
; -
不存在? 调用
createUserWithPhone()
创建新用户并保存; - 将最终
UserDTO
放入 session,并返回结果(blog.csdn.net)。
三、登录状态控制
🧾3.1 基于 Session 与 ThreadLocal 的登录拦截
-
自定义
LoginInterceptor
:- 判断 session 中有无
user
; - 存在则放入
UserHolder(ThreadLocal)
,否则返回 401(blog.csdn.net)。
- 判断 session 中有无
在 SpringMVC
MvcConfig
中注册拦截器,并排除无需登录的路径(blog.csdn.net)。
3.2 DTO 隐藏敏感信息
- 定义
UserDTO
,仅包含必要字段 (id
,nickName
,icon
); - 拦截器和登录逻辑均使用
UserDTO
,避免暴露敏感信息(blog.csdn.net)。
四、Redis 替代 Session
🚀4.1 为什么用 Redis?
- Session 存于单台机器,集群模式下存在用户登录丢失问题;
- Redis 提供跨实例共享,并且能设置过期时间(blog.csdn.net)。
💾4.2 重构存储流程
-
sendCode()
改存在 Redis:stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, TTL)
; -
login()
:- 验证码比对;
- 用户存在时生成
UUID
token; - 用 Hash 存储用户信息到 Redis,设置过期时间;
- 返回 token 作为登录凭证(blog.csdn.net)。
五、Token 验证与刷新机制
⏳5.1 登录验证(Refresh + Login 拦截器)
-
RefreshTokenInterceptor
(order=0)拦截所有请求:- 从
authorization
header 获取 token; - 在 Redis 查 hash 并放入
UserHolder
,并刷新过期时间(blog.csdn.net)。
- 从
LoginInterceptor
(order=1)针对敏感路径再次校验UserHolder
是否存在,不存在则返回 401。
⚠️5.2 类型转换 Bug 修复
- 将 token 存入 Hash 时,使用
CopyOptions
强制将所有 value 转为字符串,避免类型转换异常。
六、架构总结
模块 | 技术 / 方法 |
---|---|
前端部署 | Nginx + 静态资源发布 |
登录流程 | 验证码发送 → 比对 → 创建/查询用户 → Token 返回 |
存储手段 | Session → Redis(String + Hash) |
登录校验 | 两级拦截器(Refresh + Login) |
安全与性能 | DTO 隐藏敏感信息 + Redis token 刷新维护登录状态 |
🧩 总体评价
- ✅ 思路清晰:从前端部署、发送验证码、Redis 存储、拦截器验证,到 token 刷新,全流程贯通。
- ✅ 可扩展性强:切换 Redis 后支持集群,无状态 SSOToken。
- ✅ 细节考虑周到:防止敏感信息泄漏、强制类型转换、token 刷新机制等。
如果你希望,我可以为你整理该模块的关键类(Controller、Service、Interceptor 等)的完整代码,或者帮你实现简化版 demo,甚至讲解如何在 MyBatis‑Plus 中进行配置,随时告诉我!