基于Spring Boot与Redis的令牌主动失效机制实现

打印 上一主题 下一主题

主题 1730|帖子 1730|积分 5190

前言

在当代Web系统中,用户认证是一个核心问题,尤其是在分布式系统和微服务架构中,如何高效、安全地管理用户登录状态显得尤为重要。通常,系统通过令牌(Token)来举行身份验证,令牌的生命周期控制对于安全性非常关键。当用户修改密码等敏感操纵后,确保其之前的令牌失效,是一种常用的安全策略,可以有用防止凭据被盗后恶意访问的风险。本文将具体介绍基于Spring Boot和Redis实现令牌主动失效机制的设计与实现思绪,资助读者理解和应用该方案来进步系统的安全性和稳定性。
1. 项目结构和依赖设置

起首,我们须要基于Spring Boot搭建一个简朴的Web项目,同时集成Redis作为缓存数据库,用于存储和管理用户令牌的状态信息。通过引入Redis,能够有用控制令牌的失效机制,从而实现对用户认证的动态管理。

1.1 项目依赖设置

在项目的pom.xml中添加如下依赖,用于集成Redis:
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
  5. <dependency>
  6.     <groupId>org.springframework.boot</groupId>
  7.     <artifactId>spring-boot-starter-web</artifactId>
  8. </dependency>
复制代码
1.2 Redis毗连设置

在application.yml中设置Redis的毗连信息:
  1. spring:
  2.   redis:
  3.     host: localhost
  4.     port: 6379
  5.     timeout: 6000ms
  6.     lettuce:
  7.       pool:
  8.         max-active: 8
  9.         max-idle: 2
  10.         min-idle: 1
  11.         max-wait: -1ms
复制代码
该设置将毗连本地的Redis实例,并定义了毗连池的基本参数。具体参数根据项目需求可以进一步调整。
2. 令牌主动失效机制的实现流程


在实现令牌主动失效机制时,我们须要举行三步操纵:

  • 用户登录乐成后,系统会生成一个Token并将其存储在Redis中。
  • 在后续的每次请求中,通过拦截器从Redis中验证令牌的有用性。
  • 当用户修改密码等操纵乐成后,系统主动删除Redis中的Token,使之前的令牌失效。
下面将逐步实现上述功能。
2.1 登录乐成后将令牌存储到Redis中

起首,在用户登录乐成的情况下,系统会生成一个Token。为了方便解说,这里采用一个简朴的UUID作为Token示例。生成的Token不仅返回给前端,也会同步存储到Redis中,并设置肯定的有用时间(如1小时)。
示例代码如下:
  1. @Autowired
  2. private StringRedisTemplate stringRedisTemplate;
  3. public String login(String username, String password) {
  4.     // 生成Token
  5.     String token = UUID.randomUUID().toString();
  6.     // 将Token存储到Redis中,有效期1小时
  7.     ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
  8.     operations.set(token, token, 1, TimeUnit.HOURS);
  9.     // 返回给用户的响应中包含Token
  10.     return token;
  11. }
复制代码
上述代码通过StringRedisTemplate的opsForValue方法,将Token以键值对的情势存储到Redis中。Redis缓存会定时清除过期数据,因此可以避免手动管理令牌的过期处理。
2.2 使用拦截器验证令牌

每次用户请求时,我们须要验证用户携带的Token是否有用。通过Spring的拦截器机制,可以在请求进入控制器之前检查Redis中的Token,判断其是否有用。若Token无效或已过期,则拒绝访问。
拦截器代码如下:
  1. public class LoginInterceptor implements HandlerInterceptor {
  2.     @Autowired
  3.     private StringRedisTemplate stringRedisTemplate;
  4.     @Override
  5.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  6.         // 从请求头中获取Token
  7.         String token = request.getHeader("Authorization");
  8.         if (token == null || token.isEmpty()) {
  9.             throw new RuntimeException("缺少令牌");
  10.         }
  11.         // 从Redis中查询Token
  12.         ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
  13.         String redisToken = operations.get(token);
  14.         if (redisToken == null) {
  15.             // Token不存在或已过期,抛出异常
  16.             throw new RuntimeException("无效的令牌");
  17.         }
  18.         // Token有效,继续处理请求
  19.         return true;
  20.     }
  21. }
复制代码
在LoginInterceptor中,我们通过StringRedisTemplate的opsForValue方法获取Redis中的Token并与请求携带的Token对比。假如Token不存在,则直接拒绝该请求。若Token存在且有用,继续举行请求处理。
2.3 用户修改密码后删除旧令牌

当用户乐成修改密码时,须要确保之前的Token立刻失效。因此,乐成修改密码后,我们须要从Redis中删除该用户的Token记载,防止旧Token被再次使用。
在修改密码的业务逻辑中,加入删除Token的代码:
  1. public void changePassword(String username, String newPassword) {
  2.     // 假设用户验证通过并修改了密码
  3.     // 删除Redis中的旧Token
  4.     String token = getCurrentTokenForUser(username); // 从上下文或数据库中获取当前用户的Token
  5.     ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
  6.     operations.getOperations().delete(token);
  7. }
复制代码
在上述代码中,通过getOperations().delete()方法删除Token,使得旧Token立刻失效。如许用户在修改密码后须要重新登录,保证了账户的安全性。
3. Redis的设置与测试

为了确保上述逻辑的正确性和Redis的稳定性,发起在开辟阶段通过单元测试验证Redis的毗连和数据操纵。
  1. @SpringBootTest
  2. class RedisTest {
  3.     @Autowired
  4.     private StringRedisTemplate stringRedisTemplate;
  5.     @Test
  6.     public void testSet() {
  7.         ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
  8.         operations.set("username", "zhangsan");
  9.         operations.set("id", "1", 15, TimeUnit.SECONDS);
  10.         // 检查存储的值
  11.         String username = operations.get("username");
  12.         System.out.println("用户名:" + username);
  13.     }
  14. }
复制代码
以上代码将username和id存储到Redis中,并设置了15秒的有用期。通过单元测试,可以直观地验证Redis的写入和有用期的功能是否正常工作。
4. 可能的扩展与优化

在实际应用中,可以进一步对该令牌失效机制举行扩展和优化:


  • 基于用户ID管理Token:可以在Redis中以userId为键,存储用户当前的Token,如许方便管理用户的多个Token(如多设备登录)。
  • 使用JWT(JSON Web Token):在Token中加入用户的相关信息(如用户ID、权限等),以淘汰对Redis的依赖。不过仍需在修改密码等场景下失效Token。
  • 动态调整Token有用期:可以根据用户的活泼度或敏感操纵动态调整Token的过期时间,进一步进步系统的机动性。
结语

本文具体介绍了基于Spring Boot和Redis实现令牌主动失效机制的完整流程,并提供了关键代码示例。通过将Token存储在Redis中并在须要时主动删除,确保了用户在修改密码等操纵后的Token立刻失效,从而有用增强了系统的安全性。这种方案在实际开辟中具有良好的应用价值。通过得当扩展和优化,还可以满足更复杂的业务需求,为用户提供更优质的服务体验。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我爱普洱茶

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表