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的认证流程
使用过程中遇到的问题和解决过程
问题:小程序端使用的接口和后台管理员使用的接口有重叠,因此比较难以自定义权限验证规则,无法配置路由拦截鉴权。
解决方法:通过注解进行鉴权。优点是可以明确地为特定方法加以权限验证,缺点是需要对分散在各个角落的代码都进行注解添加。
当然还有一种方法,不过由于时间有限来不及修改,就是将小程序端和后台所需要使用到的接口分包,在不同包下进行管理,这样就不会出现路由的冲突。
总结
Satoken可以说是目前体验过最轻量的权限验证框架了,它非常方便,上手快速,对新手小白也挺友好,集成的功能也很多,只不过本次实践中需求没有那么多因此使用和体验到的有限。
Satoken是一款开源的框架,它目前仍然处于频繁更新进步的时期,时不时就有新的version,之前曾经踩过的坑就是按照开发手册上面的步骤编写代码,却发现某个接口始终无法接收参数,一开始以为是参数的格式或内容有问题,检查了许久,后面查阅它的更新日志,才发现自己当前的version并还未支持,需要修改pom.xml中的version。
希望将来Satoken能够越来越强大!