设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间20 现在时间20 缓存数据 和聪明人交流,和靠谱的人恋爱,和进取的人共事,和幽默的人随行。晚安!

和聪明人交流,和靠谱的人恋爱,和进取的人共事,和幽默的人随行。晚安!

查看: 240|回复: 1

Redis实现会话管理和token认证的示例代码

[复制链接]

  离线 

TA的专栏

  • 打卡等级:常驻代表
  • 打卡总天数:31
  • 打卡月天数:0
  • 打卡总奖励:402
  • 最近打卡:2025-11-18 02:34:34
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
390
主题
320
精华
0
金钱
1478
积分
774
注册时间
2023-2-11
最后登录
2025-11-18

发表于 2025-9-1 08:19:02 | 显示全部楼层 |阅读模式
在现代Web应用中,会话管理身份认证是实现用户登录、权限管理等功能的基础。传统的会话管理通过服务器端保存会话信息来实现,但随着应用的扩展,尤其在分布式系统中,这种方式的局限性逐渐显现。Redis作为分布式缓存系统,具备高性能和高可用性,能够很好地解决分布式环境下的会话管理和Token认证问题。
本教程将介绍如何基于Redis和Spring Boot 实现会话管理与Token认证,确保应用在高并发、分布式架构中具备良好的性能和扩展性。

一、使用场景


  • 分布式系统:当系统部署在多个服务实例上时,服务器本地的Session无法跨实例共享,而Redis能作为集中式存储,帮助管理所有实例的会话信息。
  • 无状态认证:基于Token认证机制的实现,特别是JWT(JSON Web Token),适用于用户登录后通过Token进行认证,避免在每次请求时重新查询数据库或读取Session。
  • 高并发场景:在高并发的情况下,Redis的高吞吐量和低延迟能够保证会话管理和认证机制的高效性。

二、原理解析


1. 会话管理

传统的会话管理通过在服务器端保存用户的会话状态(Session),并通过客户端(通常是浏览器)保存的Session ID与服务器进行匹配,来确定用户身份。在分布式环境下,本地Session机制无法保证跨实例共享,而Redis作为集中式存储,能够提供跨服务实例的会话共享机制。

2. Token认证

Token认证,尤其是基于JWT的认证方式,是一种无状态认证方案。与传统的Session机制不同,JWT将用户信息封装在Token中,发送给客户端,客户端在后续请求中携带该Token进行认证,服务器通过验证Token来确定用户身份。Redis可以用作存储Token的有效期或与其他用户数据的映射。

3. Redis在会话管理和Token认证中的角色


  • 会话管理:将用户的会话信息存储在Redis中,保证分布式系统中不同实例对会话的共享访问。
  • Token认证:存储Token的有效性和用户信息,或用于存储黑名单Token(已失效或已注销的Token)。

三、解决方案实现


1. 环境配置

首先,在
  1. pom.xml
复制代码
中添加Redis和Spring Security相关依赖:
  1. <dependencies>
  2.     <!-- Spring Boot Web -->
  3.     <dependency>
  4.         <groupId>org.springframework.boot</groupId>
  5.         <artifactId>spring-boot-starter-web</artifactId>
  6.     </dependency>
  7.    
  8.     <!-- Redis -->
  9.     <dependency>
  10.         <groupId>org.springframework.boot</groupId>
  11.         <artifactId>spring-boot-starter-data-redis</artifactId>
  12.     </dependency>

  13.     <!-- Spring Security -->
  14.     <dependency>
  15.         <groupId>org.springframework.boot</groupId>
  16.         <artifactId>spring-boot-starter-security</artifactId>
  17.     </dependency>

  18.     <!-- JWT Token -->
  19.     <dependency>
  20.         <groupId>io.jsonwebtoken</groupId>
  21.         <artifactId>jjwt-api</artifactId>
  22.         <version>0.11.2</version>
  23.     </dependency>
  24.     <dependency>
  25.         <groupId>io.jsonwebtoken</groupId>
  26.         <artifactId>jjwt-impl</artifactId>
  27.         <version>0.11.2</version>
  28.     </dependency>
  29.     <dependency>
  30.         <groupId>io.jsonwebtoken</groupId>
  31.         <artifactId>jjwt-jackson</artifactId>
  32.         <version>0.11.2</version>
  33.     </dependency>
  34. </dependencies>
复制代码
  1. application.yml
复制代码
中配置Redis:
  1. spring:
  2.   redis:
  3.     host: localhost
  4.     port: 6379
  5.     timeout: 6000ms
复制代码
2. Redis会话管理实现

在Spring Boot中,我们可以通过Redis来管理会话信息,下面的示例代码展示如何使用Redis来存储用户会话信息。
配置Redis序列化器
为了使得对象能够存储在Redis中,我们需要配置Redis的序列化方式。
  1. @Configuration
  2. public class RedisConfig {

  3.     @Bean
  4.     public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
  5.         RedisTemplate<String, Object> template = new RedisTemplate<>();
  6.         template.setConnectionFactory(connectionFactory);
  7.         
  8.         // 设置Key和Value的序列化器
  9.         template.setKeySerializer(new StringRedisSerializer());
  10.         template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
  11.         
  12.         return template;
  13.     }
  14. }
复制代码
使用Redis存储Session信息
我们可以在用户登录后将会话信息存入Redis中。
  1. @Service
  2. public class SessionService {

  3.     @Autowired
  4.     private RedisTemplate<String, Object> redisTemplate;

  5.     public void saveSession(String sessionId, Object sessionData) {
  6.         redisTemplate.opsForValue().set(sessionId, sessionData, 30, TimeUnit.MINUTES); // 会话有效期30分钟
  7.     }

  8.     public Object getSession(String sessionId) {
  9.         return redisTemplate.opsForValue().get(sessionId);
  10.     }

  11.     public void deleteSession(String sessionId) {
  12.         redisTemplate.delete(sessionId);
  13.     }
  14. }
复制代码
3. Token认证实现

JWT生成与解析
JWT是无状态的认证方式,将用户信息封装在Token中,通过数字签名保证Token的安全性。我们使用
  1. jjwt
复制代码
库来生成和解析JWT。
JWT工具类
  1. @Service
  2. public class JwtTokenProvider {

  3.     private static final String SECRET_KEY = "yourSecretKey";

  4.     // 生成Token
  5.     public String generateToken(String username) {
  6.         return Jwts.builder()
  7.                 .setSubject(username)
  8.                 .setIssuedAt(new Date())
  9.                 .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // Token有效期1小时
  10.                 .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
  11.                 .compact();
  12.     }

  13.     // 解析Token
  14.     public String getUsernameFromToken(String token) {
  15.         return Jwts.parser()
  16.                 .setSigningKey(SECRET_KEY)
  17.                 .parseClaimsJws(token)
  18.                 .getBody()
  19.                 .getSubject();
  20.     }

  21.     // 验证Token是否过期
  22.     public boolean isTokenExpired(String token) {
  23.         Date expiration = Jwts.parser()
  24.                 .setSigningKey(SECRET_KEY)
  25.                 .parseClaimsJws(token)
  26.                 .getBody()
  27.                 .getExpiration();
  28.         return expiration.before(new Date());
  29.     }
  30. }
复制代码
JWT拦截器实现
为了在每次请求时验证Token的有效性,我们可以通过拦截器在请求到达控制器之前进行校验。
  1. @Component
  2. public class JwtAuthenticationFilter extends OncePerRequestFilter {

  3.     @Autowired
  4.     private JwtTokenProvider jwtTokenProvider;

  5.     @Override
  6.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
  7.         String token = getTokenFromRequest(request);
  8.         
  9.         if (token != null && !jwtTokenProvider.isTokenExpired(token)) {
  10.             String username = jwtTokenProvider.getUsernameFromToken(token);
  11.             // 在SecurityContext中设置认证信息
  12.             UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
  13.             SecurityContextHolder.getContext().setAuthentication(authentication);
  14.         }
  15.         
  16.         filterChain.doFilter(request, response);
  17.     }

  18.     private String getTokenFromRequest(HttpServletRequest request) {
  19.         String bearerToken = request.getHeader("Authorization");
  20.         if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
  21.             return bearerToken.substring(7);
  22.         }
  23.         return null;
  24.     }
  25. }
复制代码
将拦截器添加到Spring Security配置中
我们需要将
  1. JwtAuthenticationFilter
复制代码
加入到Spring Security的过滤器链中。
  1. @Configuration
  2. @EnableWebSecurity
  3. public class SecurityConfig extends WebSecurityConfigurerAdapter {

  4.     @Autowired
  5.     private JwtAuthenticationFilter jwtAuthenticationFilter;

  6.     @Override
  7.     protected void configure(HttpSecurity http) throws Exception {
  8.         http
  9.             .csrf().disable()
  10.             .authorizeRequests()
  11.             .antMatchers("/login", "/register").permitAll()  // 登录、注册请求不需要认证
  12.             .anyRequest().authenticated()
  13.             .and()
  14.             .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
  15.     }
  16. }
复制代码
4. Token与Redis的结合

为了进一步增强安全性,我们可以将生成的Token存储在Redis中,并设置一个过期时间。当Token失效或用户登出时,将其从Redis中移除。
  1. @Service
  2. public class TokenService {

  3.     @Autowired
  4.     private RedisTemplate<String, Object> redisTemplate;
  5.     @Autowired
  6.     private JwtTokenProvider jwtTokenProvider;

  7.     public String createToken(String username) {
  8.         String token = jwtTokenProvider.generateToken(username);
  9.         redisTemplate.opsForValue().set(username, token, 1, TimeUnit.HOURS);  // Token存储在Redis中,1小时过期
  10.         return token;
  11.     }

  12.     public boolean validateToken(String token) {
  13.         String username = jwt
复制代码
  1.         String username = jwtTokenProvider.getUsernameFromToken(token);
  2.         String redisToken = (String) redisTemplate.opsForValue().get(username);
  3.         return token.equals(redisToken) &amp;&amp; !jwtTokenProvider.isTokenExpired(token);
  4.     }

  5.     public void invalidateToken(String username) {
  6.         redisTemplate.delete(username);  // 从Redis中移除Token
  7.     }
  8. }
复制代码
5. 登录接口实现

用户登录成功后,生成Token并存储到Redis中,同时将Token返回给客户端。客户端在后续的请求中携带此Token。
  1. @RestController
  2. @RequestMapping("/auth")
  3. public class AuthController {

  4.     @Autowired
  5.     private TokenService tokenService;
  6.     @Autowired
  7.     private AuthenticationManager authenticationManager;

  8.     @PostMapping("/login")
  9.     public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
  10.         try {
  11.             // 认证用户
  12.             Authentication authentication = authenticationManager.authenticate(
  13.                 new UsernamePasswordAuthenticationToken(
  14.                     loginRequest.getUsername(), loginRequest.getPassword()));
  15.             
  16.             SecurityContextHolder.getContext().setAuthentication(authentication);
  17.             
  18.             // 生成Token并存储到Redis
  19.             String token = tokenService.createToken(loginRequest.getUsername());
  20.             
  21.             return ResponseEntity.ok(new JwtResponse(token));
  22.         } catch (AuthenticationException e) {
  23.             return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Authentication failed");
  24.         }
  25.     }

  26.     @PostMapping("/logout")
  27.     public ResponseEntity<?> logout(HttpServletRequest request) {
  28.         String token = getTokenFromRequest(request);
  29.         if (token != null) {
  30.             String username = jwtTokenProvider.getUsernameFromToken(token);
  31.             tokenService.invalidateToken(username);  // 从Redis中移除Token
  32.         }
  33.         return ResponseEntity.ok("Logout successful");
  34.     }

  35.     private String getTokenFromRequest(HttpServletRequest request) {
  36.         String bearerToken = request.getHeader("Authorization");
  37.         if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
  38.             return bearerToken.substring(7);
  39.         }
  40.         return null;
  41.     }
  42. }
复制代码
6. 请求流程示例


  • 用户登录:用户提供用户名和密码,通过
    1. /auth/login
    复制代码
    接口进行登录。成功后,服务器生成JWT Token并存入Redis,并返回给客户端。
  • Token携带请求:客户端在后续的请求中,将Token放在
    1. Authorization
    复制代码
    头部中,发送到服务器。服务器在收到请求后,通过JWT解析Token,验证有效性。
  • 登出操作:用户在登出时,前端请求
    1. /auth/logout
    复制代码
    接口,服务器将用户的Token从Redis中移除,Token失效。

四、Redis会话管理与Token认证效果


  • 高效性能:Redis的高并发读写能力保证了在高并发场景下的会话存储与Token验证的高效性。
  • 分布式支持:使用Redis作为集中存储,可以确保在多实例或分布式部署环境中共享会话数据,避免本地Session的局限性。
  • 安全性增强:通过Redis存储Token以及Token的有效期控制,可以快速实现Token的失效处理,增强了安全性。

五、总结

Redis不仅能解决分布式环境下会话共享的问题,也能通过高效存储和快速读取实现了Token认证的高性能处理。在Spring Boot 中,使用Redis与JWT结合的方案为分布式架构提供了强大的认证与授权支持。
到此这篇关于Redis实现会话管理和token认证的示例代码的文章就介绍到这了,更多相关Redis 会话管理和token认证内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

  • 打卡等级:即来则安
  • 打卡总天数:20
  • 打卡月天数:0
  • 打卡总奖励:269
  • 最近打卡:2025-11-15 15:53:49
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
304
积分
42
注册时间
2023-3-11
最后登录
2025-11-15

发表于 2025-11-13 05:41:39 | 显示全部楼层
顶顶更健康!!!
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表