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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM