jjwt整合redis
时间: 2023-10-30 18:05:28 浏览: 87
整合jjwt和Redis可以实现JWT的有效期刷新。在整合过程中,你可以使用Redis存储JWT的刷新令牌和过期时间,以及使用jjwt生成和验证JWT。下面是整合jjwt和Redis的一种方法:
1. 首先,引入jjwt和Redis的相关依赖。
```xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- Redis相关依赖 -->
```
2. 创建一个JWT工具类,用于生成和解析JWT。
```java
// 导入相关包和类
public class JWTUtil {
// 密钥,用于签名
private static final String SECRET_KEY = "your-secret-key";
// 生成JWT
public static String generateToken(Map<String, Object> claims, long expiration) {
// 设置过期时间
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
// 使用jjwt库生成JWT
String token = Jwts.builder()
.setClaims(claims)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
return token;
}
// 解析JWT
public static Claims parseToken(String token) {
// 使用jjwt库解析JWT
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
return claims;
}
// 刷新JWT的过期时间
public static String refreshToken(String token, long expiration) {
Claims claims = parseToken(token);
// 更新过期时间
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
claims.setExpiration(expirationDate);
// 使用jjwt库重新生成JWT
String refreshedToken = Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
return refreshedToken;
}
}
```
3. 创建一个Redis工具类,用于存储和获取JWT的刷新令牌和过期时间。
```java
// 导入相关包和类
public class RedisUtil {
private RedisTemplate<String, Object> redisTemplate;
// 设置刷新令牌的有效期(单位:毫秒)
private static final long REFRESH_TOKEN_EXPIRATION = 30 * 60 * 1000; // 30分钟
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
// 存储刷新令牌和过期时间到Redis
public void saveRefreshToken(String username, String refreshToken) {
String key = "refreshToken:" + username;
redisTemplate.opsForValue().set(key, refreshToken, REFRESH_TOKEN_EXPIRATION, TimeUnit.MILLISECONDS);
}
// 获取刷新令牌
public String getRefreshToken(String username) {
String key = "refreshToken:" + username;
return (String) redisTemplate.opsForValue().get(key);
}
// 移除刷新令牌
public void removeRefreshToken(String username) {
String key = "refreshToken:" + username;
redisTemplate.delete(key);
}
}
```
4. 创建一个JWT拦截器,用于拦截请求并验证JWT的有效性。在拦截器中可以通过RedisUtil获取刷新令牌,并使用JWTUtil刷新JWT。
```java
// 导入相关包和类
public class JWTInterceptor implements HandlerInterceptor {
private RedisUtil redisUtil;
public JWTInterceptor(RedisUtil redisUtil) {
this.redisUtil = redisUtil;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从请求头中获取JWT
String token = request.getHeader("Authorization");
// 验证JWT的有效性
if (token != null) {
try {
Claims claims = JWTUtil.parseToken(token);
// 验证JWT的签名
// 如果JWT过期,则刷新JWT
if (claims.getExpiration().before(new Date())) {
String username = claims.getSubject();
String refreshToken = redisUtil.getRefreshToken(username);
if (refreshToken != null && refreshToken.equals(token)) {
String newToken = JWTUtil.refreshToken(token, JWTUtil.EXPIRATION);
response.setHeader("Authorization", newToken);
redisUtil.removeRefreshToken(username);
redisUtil.saveRefreshToken(username, newToken);
} else {
// 刷新令牌无效或已过期,拒绝访问
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
}
// 验证通过,放行请求
return true;
} catch (ExpiredJwtException e) {
// JWT过期,拒绝访问
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
}
// 没有JWT,拒绝访问
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
}
```
5. 配置拦截器,将JWT拦截器添加到Spring MVC的拦截器链中。
```java
// 导入相关包和类
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
private RedisTemplate<String, Object> redisTemplate;
public InterceptorConfig(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor(new RedisUtil(redisTemplate)))
.addPathPatterns("/**")
.excludePathPatterns("/loginController/login");
}
}
```
通过以上步骤,你可以实现jjwt和Redis的整合,达到刷新JWT的目的。在拦截器中,当JWT过期时,会从Redis中获取刷新令牌并重新生成JWT,同时更新响应头中的Authorization字段,并将新生成的刷新令牌存储到Redis中。这样,当下次请求到达时,拦截器会再次验证JWT的有效性,并根据需要刷新JWT。
请注意,以上只是一种实现方式,你可以根据自己的需求进行调整和改进。
阅读全文