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)