前后端分离项目,后端是如何处理前端传递的token?

前后端分离项目中,在不使用 SpringSecurityShiro 安全框架的情况下,后端是如何处理前段传递的 token 的呢?

简单说一个场景,在一个非常小的项目中,由于业务逻辑比较简单,也没有啥安全要求,所以决定不采用 SpringSecurityShiro 等安全框架,但由于大部分方法都会用到当前的用户信息,所以决定对前端传递的用户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年专科毕业后,期间一度迷茫,最近我创建了一个公众号用来记录自己的成长。

posted @ 2020-03-04 14:35  niceyoo  阅读(7656)  评论(0编辑  收藏  举报