package com.roma.romaapi.interceptor; import com.auth0.jwt.exceptions.AlgorithmMismatchException; import com.auth0.jwt.exceptions.SignatureVerificationException; import com.auth0.jwt.exceptions.TokenExpiredException; import com.auth0.jwt.interfaces.DecodedJWT; import com.roma.romaapi.utils.JWTUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import static com.roma.romaapi.utils.JWTUtil.REDIS_USER_EXPIRE_TIME; import static com.roma.romaapi.utils.JWTUtil.SIGN; /*** 这个拦截器就是调用了工具类中验证Token的部分 对前端用户传回的Token是否合法 以及是否保存了UID等信息进行验证 验证通过就放行 验证失败就抛出异常 由统一错误处理类承接 并最终给前端返回错误信息 ***/ @Slf4j @Component public class JWTInterceptor implements HandlerInterceptor { @Autowired private JWTUtil jwtUtil; @Autowired StringRedisTemplate stringRedisTemplate; @Override public boolean preHandle(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler) throws Exception { // 从Header中获得Token String token = request.getHeader("token"); if(token==null || token.equals("")){ throw new Exception("Header 未装载 token"); } try { // 得到签名实体 DecodedJWT verify = jwtUtil.verify(token); // 得到签名中的登录时间 String loginTimeFromToken = verify.getClaim("userLoginTime").asString(); System.out.println("token-----"+loginTimeFromToken); } catch (SignatureVerificationException e) { throw new Exception("无效Token签名"); } catch (TokenExpiredException e) { /*若抛出token过期异常,检查redis中的是否存在token以及请求头中的token与redis中的token是否相同 如果相同,说明用户仍在操作,只是请求头中的token已经过期,此时需要对token进行续期*/ // 从Redis中获取缓存中的token,判断是否过期 String userId = stringRedisTemplate.opsForValue().get(SIGN + token); if(null == userId || userId.equals("")){ throw new Exception("Original Token 无效或已过期"); } else { // 续期 String redisTokenKey = SIGN + token; stringRedisTemplate.opsForValue().set(redisTokenKey, userId, REDIS_USER_EXPIRE_TIME); return true; } // throw new Exception("token过期"); } catch (AlgorithmMismatchException e) { throw new Exception("token算法不一致"); } catch (Exception e) { throw new Exception("token无效:" + e.getMessage()); } return true; } }