Spring Security、JWT 与 Redis
作者: luote (luote) · 个人主页 luote996.cn
为什么要认证与授权
Web 应用需要区分「谁在使用系统」以及「能做什么」。认证(Authentication) 验证身份;授权(Authorization) 判断是否有权访问资源。create-luote 使用 Spring Security + JWT + Redis 实现无状态登录。
会话的两种思路
| 方案 | 特点 |
|---|---|
| Session | 服务端存会话,浏览器带 Cookie |
| JWT | 服务端不存会话,Token 自包含用户信息,适合前后端分离 |
脚手架采用 JWT:登录成功返回 token,前端存 localStorage 或 sessionStorage,后续请求 Header 携带 Authorization: Bearer <token>。
JWT 工作流程
JwtUtils 负责签发与解析;JwtAuthenticationFilter 在 Spring Security 链中拦截请求,把用户写入 SecurityContext 和 UserContext(ThreadLocal)。
Spring Security 配置要点
SecurityConfig 中常见配置:
| 配置项 | 作用 |
|---|---|
| permitAll | 放行登录、注册、验证码、Swagger |
| authenticated | 其余接口需登录 |
| JwtAuthenticationFilter | 在 UsernamePasswordAuthenticationFilter 之前解析 JWT |
| CORS | 允许前端域名跨域 |
| 异常处理器 | 401/403 返回 JSON 而非 HTML |
密码存储使用 BCrypt 哈希,不可逆,注册时对明文密码 encode,登录时 matches。
Redis 在脚手架中的用途
| 场景 | 说明 |
|---|---|
| 图形验证码 | 存 captchaKey → 验证码文本,短 TTL |
| 登录限流 | 防止暴力破解 |
| JetCache 二级缓存 | 热点数据减轻数据库压力 |
| Token 黑名单(可选扩展) | 登出后使旧 Token 失效 |
RedisUtils 封装常用 get/set/delete,避免各处重复写 RedisTemplate API。
RBAC 角色
用户表含 role 字段(如 ADMIN、USER)。Controller 或 Service 可通过 @PreAuthorize("hasRole('ADMIN')") 限制仅管理员可访问的接口。脚手架对用户管理接口做了角色校验示例。
前端如何配合
- 登录成功保存
token到 Pinia / localStorage。 - Axios 请求拦截器附加 Authorization Header。
- 响应 401 时清 token 并跳转登录页(见
request.ts)。 - 路由守卫
beforeEach检查是否已登录。
安全实践
| 实践 | 说明 |
|---|---|
| HTTPS 生产必开 | 防止 Token 被窃听 |
| 短过期 + 续期 | 脚手架支持有互动时续期 |
| 验证码 | 登录注册防机器人 |
| 限流 | 同一 IP 频繁登录拒绝 |
与 luote 脚手架的关系
| 文件 | 说明 |
|---|---|
| config/SecurityConfig.java | 安全链与 CORS |
| security/JwtAuthenticationFilter.java | Token 解析 |
| common/utils/JwtUtils.java | 签发与校验 |
| common/utils/RedisUtils.java | Redis 操作 |
| store/user.ts | 前端 token 与用户信息 |
下一章:Swagger 缓存与存储