JWT令牌与Redis的结合验证机制
2025年2月24日大约 1 分钟
JWT令牌与Redis的结合验证机制
1.用户登录成功后,后端生成一个token,并存储到redis中设置有效时长
2.前端获取到token后,存储到Pinia中,然后把token设置到请求中(统一拦截配置),携带token发起请求
3.后端登录拦截器(排除拦截登录路径),获取请求头中的token,然后把请求头中的token与redis中的就行对比,一致则为合法,放行。并且把token存储到THreadLocal中方便后续业务使用。
@Override
public Result<String> login(User user) {
HashMap<String, Object> userMap = new HashMap<>();
userMap.put("phone", user.getPhone());
userMap.put("password", user.getPassword());
String token = JwtUtil.genToken(userMap);
//把token存储到redis
stringRedisTemplate.opsForValue().set(token,token);
return Result.success(token);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("Authorization");
//没有token
if (token.isEmpty()) {
response.setStatus(401);
}
//与存储到redis中的对比token是否正确
String redisToken = stringRedisTemplate.opsForValue().get(token);
if (!redisToken.equals(token)) {
response.setStatus(401);
System.out.println("token令牌无效");
//拦截
return false;
}
//把token存储到threadLocal中
ThreadLocalUtils.set("token", token);
return true;
}
JWT令牌工具封装类
package com.tsy.tsystore;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import org.junit.jupiter.api.Test;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtil {
private static final String KEY = "tsy";
//接收业务数据,生成token并返回
public static String genToken(Map<String, Object> claims) {
return JWT.create()
.withClaim("claims", claims)
.withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 ))
.sign(Algorithm.HMAC256(KEY));
}
//接收token,验证token,并返回业务数据
public static Map<String, Object> parseToken(String token) {
return JWT.require(Algorithm.HMAC256(KEY))
.build()
.verify(token)
.getClaim("claims")
.asMap();
}
@Test
public void JwtTest(){
HashMap<String, Object> userMap = new HashMap<>();
userMap.put("username","tsy");
String token = genToken(userMap);
System.out.println("获取token"+token);
String username = (String) parseToken(token).get("username");
System.out.println("解析token"+username);
}
}