JWTInterceptor.java 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. // private RedisUtil redisUtil;
  26. @Autowired
  27. StringRedisTemplate stringRedisTemplate;
  28. @Override
  29. public boolean preHandle(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler) throws Exception {
  30. // 从Header中获得Token
  31. String token = request.getHeader("token");
  32. if(token==null || token.equals("")){
  33. throw new Exception("Header 未装载 token");
  34. }
  35. try {
  36. // 得到签名实体
  37. DecodedJWT verify = jwtUtil.verify(token);
  38. // 得到签名中的登录时间
  39. String loginTimeFromToken = verify.getClaim("userLoginTime").asString();
  40. System.out.println("token-----"+loginTimeFromToken);
  41. } catch (SignatureVerificationException e) {
  42. throw new Exception("无效Token签名");
  43. } catch (TokenExpiredException e) {
  44. /*若抛出token过期异常,检查redis中的是否存在token以及请求头中的token与redis中的token是否相同
  45. 如果相同,说明用户仍在操作,只是请求头中的token已经过期,此时需要对token进行续期*/
  46. // 从Redis中获取缓存中的token,判断是否过期
  47. String userId = stringRedisTemplate.opsForValue().get(SIGN + token);
  48. if(null == userId || userId.equals("")){
  49. throw new Exception("Original Token 无效或已过期");
  50. } else {
  51. // 续期
  52. String redisTokenKey = SIGN + token;
  53. stringRedisTemplate.opsForValue().set(redisTokenKey, userId, REDIS_USER_EXPIRE_TIME);
  54. return true;
  55. }
  56. // throw new Exception("token过期");
  57. } catch (AlgorithmMismatchException e) {
  58. throw new Exception("token算法不一致");
  59. } catch (Exception e) {
  60. throw new Exception("token无效:" + e.getMessage());
  61. }
  62. return true;
  63. }
  64. }