Token验证及自定义注解拦截注入

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 }
WebMvcConfigurerAdapter 实现类

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 }
HandlerInterceptorAdapter 实现类

自定义注解拦截注入步骤:

 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 }
HandlerMethodArgumentResolver 接口实现类

 提示:使用环境springboot(1.5.8

猜你喜欢

转载自www.cnblogs.com/eplh/p/11854412.html