Java轻量级权限认证框架——Sa-token

Java轻量级权限认证框架——Sa-token

技术概述

该技术主要适用于需要完成登录认证、权限认证、Session会话等功能的场景。在本次的项目中我们需要对管理员的权限进行管理,除此之外还有对用户进行登录验证。因此,学习该技术能够很好地为我们解决我们项目需要完成的任务内容。

技术详述

下面通过几个部分对该技术的实现和使用进行说明

  • 环境的集成

    本次项目我们后端使用的是springboot框架,为了整合satoken,首先,我们需要将Satoken的依赖添加到pom.xml中,然后在application.yml或者application.properties中设置配置,这一个过程还是十分方便简单的。

    其次,我们需要在项目目录下建立一个Util类,默认它叫做StpUtil,该类通过调用底层封装的StpLogic实现了许多业务需要用到的方法(都是静态的)。该类建立完毕后后续的几个模块可以通过调用该类的方法完成。

  • 登录认证

    在完成用户登录的账户验证后,可以通过调用 StpUtil.login(Object id); 对当前会话登录的账号id进行标记,id的建议参数类型为long | int | String

    我们可以通过调用StpUtil.checkLogin() 检验当前会话是否已经登录, 如果未登录,则抛出异常 NotLoginException

    部分代码如下:

    	  //errcode为0表示请求成功
            if(errorCode==0){
                //将获得的openid 作为loginId
                StpUserUtil.setLoginId(code2Session.getString("openid"));
                // 获取当前会话的token值,将该token值作为skey传给小程序端作为会话的维护
                String satoken=StpUserUtil.getTokenValue();
                Map map=new HashMap();
                map.put("tokenKey","satoken");
                map.put("tokenValue",satoken);
                return new ResponseDTO(errorCode,"登录成功",map);
            }
            else if(errorCode==-1){
                return new ResponseDTO(errorCode,"系统繁忙,此时请开发者稍候再试",new HashMap<>());
            }
            else if(errorCode==INVALID){
                return new ResponseDTO(errorCode,"code 无效",new HashMap<>());
            }
            else if(errorCode==OFTEN){
                return new ResponseDTO(errorCode,"频率限制,每个用户每分钟100次",new HashMap<>());
            }
            return null;
    
  • 全局异常拦截

    @ResponseBody
    @ExceptionHandler
    public String handlerException(Exception e, HttpServletRequest request, HttpServletResponse response)
                throws Exception {
            // 不同异常返回不同状态码
            String message = "";
            if(e instanceof NotRoleException) {
                // 如果是角色异常
                NotRoleException ee = (NotRoleException) e;
                message="无此角色:" + ee.getRole();
            } else if(e instanceof NotPermissionException) {
                // 如果是权限异常
                NotPermissionException ee = (NotPermissionException) e;
                message="无此权限:" + ee.getCode();
            } else if(e instanceof DisableLoginException) {
                // 如果是被封禁异常
                DisableLoginException ee = (DisableLoginException) e;
                message="账号被封禁:" + ee.getDisableTime() + "秒后解封";
            } else {
                // 普通异常, 输出:500 + 异常信息
                throw e;
            }
    
            response.setStatus(403);
            // 返回给前端
            return message;
        }
    
  • 注解鉴权

    • 权限验证基于注解,首先Config包下建立拦截器,并注册
    @Configuration
    public class SaTokenConfigure implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
          
            registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
        }
    }
    
    • 在需要验证的地方加入注解
        @SaCheckPermission("notice-add")
        @ResponseBody
        @PostMapping("/publish")
        public ResponseDTO publishNotice(@RequestBody @Validated({NoticeDO.Insert.class}) NoticeDO notice){
            noticeService.publishNotice(notice);
            return ResponseUtil.getSuccessResponse("发布成功",new HashMap<>());
        }
    

    例如公告的发布,需要有权限'notice-add',该方法才能生效;否则需要给出权限不足的提示。

下面给出Satoken的认证流程

sa-token-rz

使用过程中遇到的问题和解决过程

问题:小程序端使用的接口和后台管理员使用的接口有重叠,因此比较难以自定义权限验证规则,无法配置路由拦截鉴权。

解决方法:通过注解进行鉴权。优点是可以明确地为特定方法加以权限验证,缺点是需要对分散在各个角落的代码都进行注解添加。

当然还有一种方法,不过由于时间有限来不及修改,就是将小程序端和后台所需要使用到的接口分包,在不同包下进行管理,这样就不会出现路由的冲突。

总结

Satoken可以说是目前体验过最轻量的权限验证框架了,它非常方便,上手快速,对新手小白也挺友好,集成的功能也很多,只不过本次实践中需求没有那么多因此使用和体验到的有限。

Satoken是一款开源的框架,它目前仍然处于频繁更新进步的时期,时不时就有新的version,之前曾经踩过的坑就是按照开发手册上面的步骤编写代码,却发现某个接口始终无法接收参数,一开始以为是参数的格式或内容有问题,检查了许久,后面查阅它的更新日志,才发现自己当前的version并还未支持,需要修改pom.xml中的version。

希望将来Satoken能够越来越强大!

参考文献

Sa-toekn开发手册

posted @ 2021-06-28 10:39  不到65kg不改名  阅读(1642)  评论(0编辑  收藏  举报