springboot+redis+jwt报错快照

springboot+redis+jwt报错

暂未找到最好的解决方案(不是最优,先试用这解决一临时需求)

今天重启游戏服务器在连接redis数据库时突然报错:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.

究其原因是因为强制把redis快照关闭了导致不能持久化的问题,在网上查了一些相关解决方案,通过stop-writes-on-bgsave-error值设置为no即可避免这种问题。

有两种修改方法,一种是通过redis命令行修改,另一种是直接修改redis.conf配置文件

命令行修改方式示例:

127.0.0.1:6379> config set stop-writes-on-bgsave-error no

修改redis.conf文件:vi打开redis-server配置的redis.conf文件,然后使用搜索匹配模式:stop定位2下到stop-writes-on-bgsave-error字符串所在位置,接着把后面的yes设置为no即可。(记得重启redis服务)

### 使用 Spring Boot、RedisJWT 实现身份验证 在现代 Web 应用程序开发中,使用 JWT(JSON Web Token)作为无状态的身份验证机制是一种常见的方式。为了增强系统的安全性并支持分布式部署场景下的会话管理,可以结合 Redis 来存储和管理 JWT 的相关信息。 以下是基于 Spring Boot 3 + Spring Security 6 + JWT + Redis 的实现方案: #### 1. **项目依赖** 首先,在 `pom.xml` 文件中添加必要的依赖项: ```xml <dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- JWT --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <scope>runtime</scope> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <scope>runtime</scope> <version>0.11.5</version> </dependency> <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- MySQL and MyBatis (Optional, if using database for user management) --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.1</version> </dependency> </dependencies> ``` --- #### 2. **JWT 工具类** 创建一个工具类用于生成和解析 JWT Token。 ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; public class JwtUtil { private static final String SECRET_KEY = "your_secret_key"; // 密钥需安全保存 public String generateToken(String username) { return Jwts.builder() .setSubject(username) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } public Claims parseToken(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); } } ``` --- #### 3. **Redis 配置** 通过 Redis 缓存用户的 Token 及其有效期。 ```java @Configuration public class RedisConfig { @Bean public LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(); // 默认连接本地 Redis } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // JSON序列化 return template; } } ``` --- #### 4. **登录逻辑** 当用户成功登录后,生成 JWT 并将其存储到 Redis 中。 ```java @RestController @RequestMapping("/auth") public class AuthController { @Autowired private UserService userService; // 假设有一个服务来处理用户数据 @Autowired private JwtUtil jwtUtil; @Autowired private RedisTemplate<String, Object> redisTemplate; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest request) { User user = userService.authenticate(request.getUsername(), request.getPassword()); if (user != null) { String token = jwtUtil.generateToken(user.getUsername()); // 将 Token 存入 Redis,设置过期时间为 1 天 redisTemplate.opsForValue().set("AUTH:" + token, user.getId(), Duration.ofDays(1)); return ResponseEntity.ok(Map.of("token", token)); } else { throw new RuntimeException("Invalid credentials"); } } } ``` --- #### 5. **拦截器与过滤器** 在请求到达控制器之前,检查 Token 是否有效以及是否存在 Redis 中。 ```java @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { @Autowired private JwtUtil jwtUtil; @Autowired private RedisTemplate<String, Object> redisTemplate; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String authHeader = request.getHeader("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { try { String token = authHeader.substring(7); // 提取 Token // 检查 Token 是否存在于 Redis 中 Boolean existsInRedis = redisTemplate.hasKey("AUTH:" + token); if (!existsInRedis) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } // 解析 Token 获取用户名 Claims claims = jwtUtil.parseToken(token); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( claims.getSubject(), null, Collections.emptyList() ); SecurityContextHolder.getContext().setAuthentication(authentication); } catch (Exception e) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); return; } } filterChain.doFilter(request, response); } } ``` --- #### 6. **Spring Security 配置** 配置 Spring Security 以启用自定义过滤器。 ```java @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeHttpRequests() .requestMatchers("/auth/login").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } } ``` --- ### 总结 上述方法展示了如何利用 Spring Boot、RedisJWT 构建一套完整的身份验证解决方案[^1]。该方案不仅实现了无状态的 Token 认证,还借助 Redis 提供了高效的 Token 管理能力[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值