package com.tiesheng.login.config; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import com.tiesheng.annotation.token.TokenIgnore; import com.tiesheng.login.pojos.RequestUserInfo; import com.tiesheng.login.service.TsLoginConfigurer; import com.tiesheng.util.config.TsTokenConfig; import com.tiesheng.util.exception.ApiException; import com.tiesheng.util.pojos.TokenBean; import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; import org.springframework.context.annotation.Configuration; import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.util.List; @Configuration public class TokenWebMvcConfigurer implements WebMvcConfigurer { @Resource TsTokenConfig tsTokenConfig; @Resource TsLoginConfigurer tsLoginConfigurer; @Override public void addArgumentResolvers(List resolvers) { resolvers.add(new HandlerMethodArgumentResolver() { @Override public boolean supportsParameter(MethodParameter parameter) { return TokenBean.class.isAssignableFrom(parameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { String header = webRequest.getHeader(TsTokenConfig.TOKEN_KEY); boolean thrExp = true; Method method = parameter.getMethod(); if (method != null) { TokenIgnore annotation = method.getAnnotation(TokenIgnore.class); thrExp = annotation == null; } TokenBean tokenBean = tsTokenConfig.validToken(header, thrExp); return BeanUtil.copyProperties(tokenBean, parameter.getParameterType()); } }); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerInterceptor() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 非接口类直接跳过 if (!(handler instanceof HandlerMethod)) { return true; } String requestURI = request.getRequestURI(); String[] ignorePaths = tsTokenConfig.getIgnorePaths(); if (ObjUtil.isNotEmpty(ignorePaths)) { for (String path : ignorePaths) { if (path.contains("/**") && StrUtil.startWith(requestURI, path.replace("/**", ""))) { // 通配路径 return true; } else if (requestURI.equals(path)) { // 完整路径 return true; } } } // 过滤不要需要验证的接口(注解) HandlerMethod handlerMethod = (HandlerMethod) handler; if (handlerMethod.getBeanType() == BasicErrorController.class) { return true; } TokenIgnore annotation = handlerMethod.getBeanType().getAnnotation(TokenIgnore.class); if (annotation != null) { return true; } TokenIgnore apiTokenIgnore = handlerMethod.getMethodAnnotation(TokenIgnore.class); if (apiTokenIgnore != null) { return true; } // 验证TOKEN是否存在 TokenBean tokenBean = tsTokenConfig.validToken(request, true); // 验证用户是否存在 RequestUserInfo cachedUserInfo = tsLoginConfigurer.getCachedUserInfo(tokenBean, false); if (cachedUserInfo == null) { throw new ApiException("非法TOKEN,请重新登录"); } return true; } }); } }