一、SpringBoot 集成 Redis 步骤
1. 引入依赖
在 pom.xml 中添加 Redis 起步依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
groupId:org.springframework.boot,标识 Spring 官方项目组artifactId:spring-boot-starter-data-redis,Redis 集成的起步依赖,自动引入相关客户端和配置
2. 配置 Redis 连接信息
在 application.yml 中配置 Redis 连接参数:
yaml
spring:
data:
redis:
host: localhost # Redis 服务器地址
port: 6379 # Redis 默认端口
# password: 你的密码 # 可选,有密码时配置
# database: 0 # 可选,指定使用的数据库编号,默认0
3. 核心 API:StringRedisTemplate
SpringBoot 自动配置了 StringRedisTemplate,专门用于字符串类型的 Redis 操作,常用方法:
java
运行
@Autowired
private StringRedisTemplate stringRedisTemplate;
// 1. 存储字符串
@Test
public void testSet() {
stringRedisTemplate.opsForValue().set("username", "如花");
}
// 2. 获取字符串
@Test
public void testGet() {
String value = stringRedisTemplate.opsForValue().get("username");
System.out.println(value); // 输出:如花
}
// 3. 带过期时间的存储(如令牌场景)
stringRedisTemplate.opsForValue().set("token:1001", "abc123", 30, TimeUnit.MINUTES);
二、基于 Redis 的令牌主动失效机制
1. 核心目标
解决传统 Token 无法主动失效的问题,实现修改密码、退出登录后,旧令牌立即失效的安全控制。
2. 完整流程
-
登录阶段:令牌存入 Redis 用户登录成功后:
- 生成唯一令牌(Token)
- 将令牌响应给前端(通常放在响应头 / 响应体中)
- 同时将令牌存入 Redis,Key 为
token:用户ID,Value 为令牌值,并设置过期时间(如 30 分钟)
示例代码:
java
运行
// 登录成功逻辑 String token = UUID.randomUUID().toString(); // 存入Redis,设置30分钟过期 stringRedisTemplate.opsForValue().set("token:" + userId, token, 30, TimeUnit.MINUTES); // 响应给前端 return Result.success(token); -
请求阶段:拦截器验证令牌 自定义
LoginInterceptor拦截所有请求,执行以下验证逻辑:- 从请求头中获取前端携带的令牌
- 从 Redis 中取出该用户对应的令牌(通过用户 ID 解析 Key)
- 比较两个令牌是否一致:
- 一致:放行请求,刷新 Redis 中令牌的过期时间
- 不一致 / Redis 中不存在:拒绝请求,返回 "未登录 / 令牌已失效"
示例代码:
java
运行
public class LoginInterceptor implements HandlerInterceptor { @Autowired private StringRedisTemplate stringRedisTemplate; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 1. 获取请求头中的token String token = request.getHeader("token"); if (token == null || token.isEmpty()) { response.setStatus(401); return false; } // 2. 解析用户ID(示例:假设token中包含用户ID,实际可通过JWT解析) String userId = parseUserIdFromToken(token); // 3. 从Redis中获取存储的token String redisToken = stringRedisTemplate.opsForValue().get("token:" + userId); // 4. 验证token是否一致 if (redisToken == null || !redisToken.equals(token)) { response.setStatus(401); return false; } // 5. 刷新过期时间 stringRedisTemplate.expire("token:" + userId, 30, TimeUnit.MINUTES); return true; } } -
主动失效阶段:删除 Redis 中的令牌 当用户执行修改密码、退出登录等操作时,直接删除 Redis 中对应的令牌:
java
运行
// 修改密码成功后 stringRedisTemplate.delete("token:" + userId); // 退出登录时 stringRedisTemplate.delete("token:" + userId);此时前端携带的旧令牌,在下次请求时会被拦截器验证失败,实现主动失效。
三、关键知识点补充
1. 为什么要用 Redis 实现令牌主动失效?
- 传统无状态 Token(如 JWT)依赖客户端过期,服务器无法主动控制,存在安全风险(如用户修改密码后,旧 Token 仍可使用)
- Redis 是高性能内存数据库,读写速度快,支持设置过期时间,适合存储临时令牌
- 通过 Redis 统一管理令牌,服务器可以随时删除令牌,实现主动失效控制
2. 令牌存储设计建议
- Key 设计 :
token:用户ID,方便快速定位和删除 - 过期时间:设置合理的过期时间(如 30 分钟),避免 Redis 内存占用过高
- 刷新机制:每次请求成功后刷新过期时间,实现 "登录态续期"
3. 注意事项
- 拦截器需要配置
excludePathPatterns放行登录、注册等无需验证的接口 - Redis 需配置持久化(如 RDB/AOF),避免重启后令牌丢失导致用户全部掉线
- 生产环境中,建议对 Redis 连接配置密码和 SSL,提升安全性