前后端分離項目中,在不使用 SpringSecurity、Shiro 安全框架的情況下,后端是如何處理前段傳遞的 token 的呢?
簡單說一個場景,在一個非常小的項目中,由於業務邏輯比較簡單,也沒有啥安全要求,所以決定不采用 SpringSecurity、Shiro 等安全框架,但由於大部分方法都會用到當前的用戶信息,所以決定對前端傳遞的用戶token進行一次公共處理。
解決思路:采用自定義注解方式,將token對應的數據自動注入到相應實體中。
最終實現效果如下,帶有 @CurrentUser 注解的 UserModel 實體會自動注入用戶信息。
@RequestMapping(value = "getUserInfo", method = {RequestMethod.POST})
@ApiOperation(value = "我是某方法")
public Result<UserModel> getUserInfo(@CurrentUser UserModel user){
return ResultUtil.success(user);
}
1、自定義解析器
實現自定義解析器需要實現 HandlerMethodArgumentResolver 接口,該接口包含兩個方法:supportsParameter + resolveArgument。
簡單說一下這兩個方法的作用:
-
supportsParameter:用於判定參數是否需要進行分解處理,說白了就是一個過濾方法,如果返回true則表示需要,並會去調用 resolveArgument() 方法。
-
resolveArgument:真正處理參數分解的方法,返回的Object對象為Controller中的參數類型對象,本文中為 UserModel。
正式開始,我們創建一個 class ,取名為 CurrentUserMethodArgumentResolver,實現上邊提到的這兩個方法:
@Component
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private UserDao userDao;
@Override
public boolean supportsParameter(MethodParameter parameter) {
/**如果參數類型是User並且有CurrentUser注解則支持**/
if (parameter.getParameterType().isAssignableFrom(UserModel.class) &&
parameter.hasParameterAnnotation(CurrentUser.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
/**取出前端Header或者是參數中攜帶的token,如下二選一**/
String token = webRequest.getHeader("token");
String token = webRequest.getParameter("token");
if (token != null) {
/**對token進行解析,比如從redis中取出token所對應的用戶標識**/
/**總之就是從token中得到用戶的唯一標識,然后從數據庫中查詢並返回**/
User user = userDao.findByUserId(用戶唯一標識userId);
UserModel result = new UserModel();
BeanUtils.copyProperties(user, result);
return result;
}
return null;
}
}
2、簡單說一下上方方法
supportsParameter:通過 UserModel 類型判斷 + CurrentUser 注解判斷,驗證是否返回 true。
resolveArgument:主要通過 webRequest 獲取 Header 或者是 Parmeter 中的 token 參數,取到參數后首先對 token 進行處理,換取用戶的唯一標識,拿到用戶唯一標識后再去數據庫查詢相應的用戶信息,然后進行一個格式轉換,畢竟有些數據還是不要直接返回給前台的好「用戶密碼等」。
至於怎么使用,最開始已經貼過代碼了,只要在 UserModel 加入 @CurrentUser 注解即可實現數據注入了,當然,前端勢必要加入 token 參數才可以:
@RequestMapping(value = "getUserInfo", method = {RequestMethod.POST})
@ApiOperation(value = "我是某方法")
public Result<UserModel> getUserInfo(@CurrentUser UserModel user){
return ResultUtil.success(user);
}
最后
博客地址:https://www.cgblog.com/niceyoo
如果覺得這篇文章有丶東西,不放關注一下我,關注是對我最大的鼓勵~
18年專科畢業后,期間一度迷茫,最近我創建了一個公眾號用來記錄自己的成長。
