在这篇文章中我们生成了token(JWT)发送给前端以及存入了redis中,那我们应该怎么使用这个token呢?
1.认证过滤器
我们需要自定义一个过滤器,这个过滤器会去获取请求头中的token,对token进行解析取出其中的uuid。
使用userid去redis中获取对应的User对象。
然后封装Authentication对象存入SecurityContextHolder
①. 创建JWT验证过滤器
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private RedisCache redisCache;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//获取token
String token = request.getHeader("token");
if (!StringUtils.hasText(token)) {
//放行
filterChain.doFilter(request, response);
return;
}
//解析token
String userid;
try {
Claims claims = JwtUtil.parseJWT(token);
userid = claims.getSubject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("token非法");
}
//从redis中获取用户信息
String redisKey = "login_user_key" + userid;
LoginUser loginUser = redisCache.getCacheObject(redisKey);
if(Objects.isNull(loginUser)){
throw new RuntimeException("用户未登录");
}
//存入SecurityContextHolder
//TODO 获取权限信息封装到Authentication中
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(loginUser,null,null);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
//放行
filterChain.doFilter(request, response);
}
}
②. 在过滤器中具体的操作
1. 解析请求头中Token
2.解析出token中的uuid
3.使用uuid从redis中获取用户的详情信息
4. 将用户信息存储到SecurityContextHolder中的ThreadLocal中,实现数据共享,给后续过滤器进行数据获取