package com.supervision.config; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.hutool.jwt.JWT; import cn.hutool.jwt.JWTUtil; import com.supervision.exception.BusinessException; import com.supervision.util.TokenUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; @Slf4j public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { //请求消息头获取用户ID String token = request.getHeader("token"); if (StrUtil.isBlank(token)) { // 如果是swagger来的接口,说明这里是测试的,会伪造一个用户 if (StrUtil.isNotBlank(request.getHeader("Knife4j-Gateway-Code"))) { cacheAuth(JWTUtil.parseToken(devActiveUser())); return true; } else { throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value()); } } JWT jwt = JWTUtil.parseToken(token); // 校验token是否过期,如果过期了,需要提示过期重新登录 checkTokenExpire(jwt); // 校验是否重复登录 UserSingleLoginConfig.checkSingleLogin(jwt); cacheAuth(jwt); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 请求结束,将用户信息从thread中移除 clearAuth(); HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } private void checkTokenExpire(JWT jwt) { Object expireTime = jwt.getPayload("expireTime"); long l = Long.parseLong(String.valueOf(expireTime)); // 校验是否比当前时间大 long currentTimeMillis = System.currentTimeMillis(); if (currentTimeMillis > l) { throw new BusinessException("用户登录已过期,请重新登录", HttpStatus.UNAUTHORIZED.value()); } } private void cacheAuth(JWT jwt) { try { JSONObject claimsJson = jwt.getPayload().getClaimsJson(); ThreadCache.USER.set(claimsJson.toString()); } catch (Exception e) { log.error("用户信息异常", e); } } private String devActiveUser() { Map map = new HashMap<>(); map.put("id", "1"); map.put("account", "test"); map.put("name", "测试账户"); return TokenUtil.creatToken(JSONUtil.toJsonStr(map)); } private void clearAuth() { ThreadCache.USER.remove(); } }