该技术主要适用于需要完成登录认证、权限认证、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;
}
注解鉴权
@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能够越来越强大!
原文:https://www.cnblogs.com/ldy316/p/14943400.html