Token验证实现步骤:
1. 实现自定义注解
1.0. @Login(拦截请求验证token,结合token实现单点登录,挂机时限) 与 @LoginUser(前台传入token转换为userID)
图片示例:
2. 拦截器的注册类
2.0. extends(继承)WebMvcConfigurerAdapter类 (继承WebMvcConfigurationSupport 类,implements(实现) WebMvcConfigurer接口,根据不同的开发环境选择不同方式)
WebMvcConfigurerAdapter : Spring内部的一种配置方式采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制

1 package com.shengwei.businessschoolapi.config; 2 3 import com.shengwei.businessschoolapi.interceptor.AuthorizationInterceptor; 4 import com.shengwei.businessschoolapi.resolver.LoginUserHandlerMethodArgumentResolver; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.context.annotation.Configuration; 7 import org.springframework.web.method.support.HandlerMethodArgumentResolver; 8 import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 9 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 10 11 import java.util.List; 12 13 @Configuration 14 public class WebLoginHandlerConfig extends WebMvcConfigurerAdapter { 15 16 @Autowired 17 private AuthorizationInterceptor authorizationInterceptor; 18 19 @Autowired 20 private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver; 21 /* 22 *重写拦截器:添加拦截请求方法 excludePathPatterns(不拦截请求) addPathPatterns(拦截的请求) 23 *authorizationInterceptor:作用:拦截器实现 实现功能:用于每次请求验证Token(结合自定义注解@Login实现) 24 */ 25 @Override 26 public void addInterceptors(InterceptorRegistry registry) { 27 registry.addInterceptor(authorizationInterceptor).excludePathPatterns("/api/wxUser/login").addPathPatterns("/api/**"); 28 } 29 /* 30 *添加参数解析器 31 *loginUserHandlerMethodArgumentResolver 实现功能如:不传参数情况下可通过@LoginUser实现数据注入(结合自定义注解@LoginUser实现) 32 */ 33 @Override 34 public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 35 argumentResolvers.add(loginUserHandlerMethodArgumentResolver); 36 } 37 }
3. 拦截器实现

1 package com.shengwei.businessschoolapi.interceptor; 2 3 import com.shengwei.businessschoolapi.annotation.Login; 4 import com.shengwei.businessschoolapi.exception.RRException; 5 import com.shengwei.businessschoolapi.model.TokenEntity; 6 import com.shengwei.businessschoolapi.service.TokenService; 7 import org.apache.commons.lang.StringUtils; 8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.stereotype.Component; 10 import org.springframework.web.method.HandlerMethod; 11 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 @Component 16 public class AuthorizationInterceptor extends HandlerInterceptorAdapter { 17 18 @Autowired 19 private TokenService tokenService; 20 21 //统一设置userId的 KEY值 22 public static final String USER_KEY = "userId"; 23 24 //前台统一token的 KEY值 25 public static final String LOGIN_TOKEN_KEY = "WM-SHOP-TOKEN"; 26 27 /* 28 * preHandle()作用:在业务处理器处理请求之前被调用 预处理 可以进行编码 安全控制等处理 29 * 30 */ 31 @Override 32 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 33 Login annotation; 34 if(handler instanceof HandlerMethod) { 35 annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class); 36 }else{ 37 return true; 38 } 39 if(annotation == null){ 40 return true; 41 } 42 //从header中获取token 43 String token = request.getHeader(LOGIN_TOKEN_KEY); 44 //如果header中不存在token,则从参数中获取token 45 if(StringUtils.isBlank(token)){ 46 token = request.getParameter("token"); 47 } 48 //token为空 49 if(StringUtils.isBlank(token)){ 50 throw new RRException("token不能为空"); 51 } 52 //查询token信息 53 TokenEntity tokenEntity = tokenService.queryByToken(token); 54 if(tokenEntity == null || tokenEntity.getExpirationTime().getTime() < System.currentTimeMillis()){ 55 throw new RRException("token失效,请重新登录"); 56 } 57 //设置userId到request里,后续根据userId,获取用户信息 58 request.setAttribute(USER_KEY, tokenEntity.getUserid()); 59 return true; 60 } 61 }
自定义注解拦截注入步骤:
1. 实现自定义注解(这里我们用(@LoginUser)
2. 添加参数解析器(这里我们用 LoginUserHandlerMethodArgumentResolver实现类)
3. 实现参数解析器

1 package com.shengwei.businessschoolapi.resolver; 2 3 import com.shengwei.businessschoolapi.annotation.LoginUser; 4 import com.shengwei.businessschoolapi.exception.RRException; 5 import com.shengwei.businessschoolapi.service.TokenService; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.core.MethodParameter; 8 import org.springframework.stereotype.Component; 9 import org.springframework.web.bind.support.WebDataBinderFactory; 10 import org.springframework.web.context.request.NativeWebRequest; 11 import org.springframework.web.method.support.HandlerMethodArgumentResolver; 12 import org.springframework.web.method.support.ModelAndViewContainer; 13 14 @Component 15 public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { 16 @Autowired 17 private TokenService tokenService; 18 19 //前台统一token的 KEY值 20 public static final String LOGIN_TOKEN_KEY = "WM-SHOP-TOKEN"; 21 22 /* 23 *getParameterType().isAssignableFrom(Long.class):为参数注入类型判断 hasParameterAnnotation(LoginUser.class)为当前注解名称判断 24 *当 retuer返回为true时 执行resolveArgument()方法 25 */ 26 @Override 27 public boolean supportsParameter(MethodParameter methodParameter) { 28 return methodParameter.getParameterType().isAssignableFrom(Long.class) && methodParameter.hasParameterAnnotation(LoginUser.class); 29 } 30 /* 31 * 注入数据方法 32 */ 33 @Override 34 public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) { 35 //获取用户token 36 String token = nativeWebRequest.getHeader(LOGIN_TOKEN_KEY); 37 if (token == null || token.isEmpty()) { 38 new RRException("没有token"); 39 } 40 //获取用户Id 41 Long userId = tokenService.getUserId(token); 42 if (userId == null) { 43 44 new RRException("请登录"); 45 } 46 return userId; 47 } 48 }
提示:使用环境springboot(1.5.8)