前后端分离项目中,在不使用 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年专科毕业后,期间一度迷茫,最近我创建了一个公众号用来记录自己的成长。