JWTInterceptor.java 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package com.roma.romaapi.interceptor;
  2. import com.auth0.jwt.exceptions.AlgorithmMismatchException;
  3. import com.auth0.jwt.exceptions.SignatureVerificationException;
  4. import com.auth0.jwt.exceptions.TokenExpiredException;
  5. import com.auth0.jwt.interfaces.DecodedJWT;
  6. import com.roma.romaapi.utils.JWTUtil;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.data.redis.core.StringRedisTemplate;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.web.servlet.HandlerInterceptor;
  12. import static com.roma.romaapi.utils.JWTUtil.REDIS_USER_EXPIRE_TIME;
  13. import static com.roma.romaapi.utils.JWTUtil.SIGN;
  14. /***
  15. 这个拦截器就是调用了工具类中验证Token的部分 对前端用户传回的Token是否合法 以及是否保存了UID等信息进行验证
  16. 验证通过就放行
  17. 验证失败就抛出异常 由统一错误处理类承接 并最终给前端返回错误信息
  18. ***/
  19. @Slf4j
  20. @Component
  21. public class JWTInterceptor implements HandlerInterceptor {
  22. @Autowired
  23. private JWTUtil jwtUtil;
  24. @Autowired
  25. StringRedisTemplate stringRedisTemplate;
  26. @Override
  27. public boolean preHandle(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler) throws Exception {
  28. // 从Header中获得Token
  29. String token = request.getHeader("token");
  30. if(token==null || token.equals("")){
  31. throw new Exception("Header 未装载 token");
  32. }
  33. try {
  34. // 得到签名实体
  35. DecodedJWT verify = jwtUtil.verify(token);
  36. // 得到签名中的登录时间
  37. String loginTimeFromToken = verify.getClaim("userLoginTime").asString();
  38. System.out.println("token-----"+loginTimeFromToken);
  39. } catch (SignatureVerificationException e) {
  40. throw new Exception("无效Token签名");
  41. } catch (TokenExpiredException e) {
  42. /*若抛出token过期异常,检查redis中的是否存在token以及请求头中的token与redis中的token是否相同
  43. 如果相同,说明用户仍在操作,只是请求头中的token已经过期,此时需要对token进行续期*/
  44. // 从Redis中获取缓存中的token,判断是否过期
  45. String userId = stringRedisTemplate.opsForValue().get(SIGN + token);
  46. if(null == userId || userId.equals("")){
  47. throw new Exception("Original Token 无效或已过期");
  48. } else {
  49. // 续期
  50. String redisTokenKey = SIGN + token;
  51. stringRedisTemplate.opsForValue().set(redisTokenKey, userId, REDIS_USER_EXPIRE_TIME);
  52. return true;
  53. }
  54. // throw new Exception("token过期");
  55. } catch (AlgorithmMismatchException e) {
  56. throw new Exception("token算法不一致");
  57. } catch (Exception e) {
  58. throw new Exception("token无效:" + e.getMessage());
  59. }
  60. return true;
  61. }
  62. }