SaToken技术分享

1.什么是SaToken

Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证权限认证Session会话单点登录OAuth2.0微服务网关鉴权 等一系列权限相关问题,简化了相对Shiro或者SpringSecurity的复杂的前置配置,比如自定义的Realm或者全局过滤器这些。

SaToekn与Shiro以及SpringSecurity对比

相同点:都具备认证授权加密会话缓存rememerMe等功能,都是一种安全认证框架。

SpringSecurity优点:

  • SpringSecurity是基于Spring进行开发的 ,需要依赖Spring Shiro是需要和Spring进行整合开发
  • SpringSecurity功能相对比Shiro更加丰富以及社区资源相对Shiro更多

Shiro优点:

  • Shiro的配置和使用比较简单而SpringSecurity相对上手比较复杂
  • Shiro是一种相对独立的容器,依赖性比较低,可以独立运行但是 Spring Security 依赖Spring容器;

saToken的优点

  • 功能相对Shiro和SpringSecurity更加全面和完整
  • 更加独立,整合项目过程中只需要引入依赖添加配置即可简化了部署的操作
  • 入门以及操作更加简单简化了类似Shiro这种需要自定义Relam的操作,官方文档是中文版的,更好理解

2.常用功能介绍

  • 登录认证 —— 单端登录、多端登录、同端互斥登录、七天内免登录
  • 权限认证 —— 权限认证、角色认证、会话二级认证
  • 踢人下线 —— 根据账号id踢人下线、根据Token值踢人下线
  • 账号封禁 —— 指定天数封禁、永久封禁、设定解封时间
  • 持久层扩展 —— 可集成Redis等专业缓存中间件,重启数据不丢失
  • 分布式会话 —— 提供jwt集成、共享数据中心两种分布式会话方案
  • 独立Redis —— 将权限缓存与业务缓存分离
  • 同端互斥登录 —— 像QQ一样手机电脑同时在线,但是两个手机上互斥登录
  • 多账号认证体系 —— 比如一个商城项目的user表和admin表分开鉴权
  • 花式token生成 —— 内置六种Token风格,还可:自定义Token生成策略、自定义Token前缀
  • 注解式鉴权 —— 优雅的将鉴权与业务代码分离
  • 路由拦截式鉴权 —— 根据路由拦截鉴权,可适配restful模式
  • 密码加密 —— 提供密码加密模块,可快速MD5、SHA1、SHA256、AES、RSA加密
  • 全局侦听器 —— 在用户登陆、注销、被踢下线等关键性操作时进行一些AOP操作
StpUtil.login(10001);    // 标记当前会话登录的账号id
StpUtil.getLoginId();    // 获取当前会话登录的账号id
StpUtil.isLogin();    // 获取当前会话是否已经登录, 返回true或false
StpUtil.logout();    // 当前会话注销登录
StpUtil.kickout(10001);    // 将账号为10001的会话踢下线
StpUtil.hasRole("super-admin");    // 查询当前账号是否含有指定角色标识, 返回true或false
StpUtil.hasPermission("user:add");    // 查询当前账号是否含有指定权限, 返回true或false
StpUtil.getTokenValueByLoginId(10001);    // 获取账号id为10001的token令牌值
StpUtil.login(10001, "PC");    // 指定设备标识登录,常用于“同端互斥登录”
StpUtil.kickout(10001, "PC");    // 指定账号指定设备标识踢下线 (不同端不受影响)
StpUtil.openSafe(120);    // 在当前会话开启二级认证,有效期为120秒
StpUtil.checkSafe();    // 校验当前会话是否处于二级认证有效期内,校验失败会抛出异常

3.使用操作流程

1.创建SpringBoot项目

2.添加依赖

<dependency><groupId>cn.dev33</groupId><artifactId>sa-token-spring-boot-starter</artifactId><version>1.29.0</version>
</dependency>

3.编写配置文件

server:# 端口port: 8081
# Sa-Token配置
sa-token: # token名称 token-name: token# token有效期,单位s 默认30天, -1代表永不过期 timeout: 2592000# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) is-concurrent: false# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) is-share: false# token风格token-style: uuid# 是否输出操作日志 is-log: true

3.启动SpringBoot项目 进行启动

4.编写测试

@Api(tags = "用户基础操作")
@RestController
@RequestMapping("/acc/")
public class LoginController {public static final String LJX = "ljx";public static final String PASSWORD = "123456";@GetMapping("doLogin")@ApiOperation("登录操作")public SaResult doLogin(String name, String pwd) {//todo 这个地方放置具体的数据库操作if (LJX.equals(name) && PASSWORD.equals(pwd)) {// 存放的是登录用户的账户accountStpUtil.login(10001);String tokenName = StpUtil.getTokenName();System.out.println("token名称是"+tokenName);String tokenValue = StpUtil.getTokenValue();System.out.println("token的值"+tokenValue);SaTokenInfo tokenInfo = StpUtil.getTokenInfo();System.out.println("token的信息参数"+tokenInfo);return SaResult.ok("登录成功");}return SaResult.error("登录失败");}@ApiOperation("判断当前的登录状态")@GetMapping("isLogin")public SaResult isLogin() {return SaResult.ok(StpUtil.isLogin() + "");}@RequestMapping("tokenInfo")@GetMapping("获取当前的token信息")public SaResult tokenInfo() {return SaResult.data(StpUtil.getTokenInfo());}@ApiOperation("账号注销登录")@GetMapping("logout")public SaResult logout() {StpUtil.logout();return SaResult.ok();}
}

4.注解式鉴权操作流程

1.编写实现StpInterface接口的类 实现获取当前登录用户的权限集合以及角色集合的操作

@Component
public class StpInterfaceImpl implements StpInterface {/*** 返回一个账号所拥有的权限码集合*/@Overridepublic List<String> getPermissionList(Object loginId, String loginType) {// todo 根据从数据库中进行查询List<String> list = new ArrayList<String>();list.add("user-add");
//        list.add("user-delete");
//        list.add("user-update");list.add("user-get");list.add("article-get");return list;}/*** 返回一个账号所拥有的角色标识集合*/@Overridepublic List<String> getRoleList(Object loginId, String loginType) {// todo 根据从数据库中进行查询List<String> list = new ArrayList<String>();list.add("admin");list.add("super-admin");return list;}
}

2.定义全局异常拦截

/*** 全局异常处理*/
@ControllerAdvice
public class GlobalException {// 全局异常拦截(拦截项目中的所有异常)@ResponseBody@ExceptionHandlerpublic AjaxJson handlerException(Exception e, HttpServletRequest request, HttpServletResponse response)throws Exception {// 不同异常返回不同状态码AjaxJson aj;if (e instanceof NotLoginException) {// 如果是未登录异常NotLoginException ee = (NotLoginException) e;aj = AjaxJson.getNotLogin().setMsg(ee.getMessage());} else if (e instanceof NotRoleException) {// 如果是角色异常NotRoleException ee = (NotRoleException) e;aj = AjaxJson.getNotJur("无此角色:" + ee.getRole());} else if (e instanceof NotPermissionException) {// 如果是权限异常NotPermissionException ee = (NotPermissionException) e;aj = AjaxJson.getNotJur("无此权限:" + ee.getCode());} else if (e instanceof DisableLoginException) {// 如果是被封禁异常DisableLoginException ee = (DisableLoginException) e;aj = AjaxJson.getNotJur("账号被封禁:" + ee.getDisableTime() + "秒后解封");} else {// 普通异常, 输出:500 + 异常信息aj = AjaxJson.getError(e.getMessage());}// 返回给前端return aj;}
}

3.使用鉴权式注解

@Api(tags = "注解鉴权测试")
@RestController
@RequestMapping("/at/")
public class AtController {@SaCheckLogin@ApiOperation("检验之后登录的用户才可以进行操作")@GetMapping("checkLogin")public SaResult checkLogin() {return SaResult.ok();}@ApiOperation("具有指定权限操作")@SaCheckPermission("user-add")@GetMapping("checkPermission")public SaResult checkPermission() {return SaResult.ok();}@ApiOperation("同时具有指定权限操作")@SaCheckPermission({"user-add", "user-delete", "user-update"})@GetMapping("checkPermissionAnd")public SaResult checkPermissionAnd() {return SaResult.ok();}@ApiOperation("具有多个指定权限中的一个操作")@SaCheckPermission(value = {"user-add", "user-delete", "user-update"}, mode = SaMode.OR)@GetMapping("checkPermissionOr")public SaResult checkPermissionOr() {return SaResult.ok();}@ApiOperation("具有指定角色才可以进行操作")@SaCheckRole("admin")@GetMapping("checkRole")public SaResult checkRole() {return SaResult.ok();}@ApiOperation("开启二级认证")@GetMapping("openSafe")public SaResult openSafe() {// todo 在这个地方添加校验是否开启二级认证// 打开二级认证,有效期为200秒StpUtil.openSafe(200);return SaResult.ok();}@ApiOperation("通过二级认证之后才可以进行操作")@SaCheckSafe@GetMapping("checkSafe")public SaResult checkSafe() {// todo 添加一些需要二级认证之后才可以进行的操作return SaResult.ok();}
}

5.路由拦截鉴权

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {/*** 注册Sa-Token 的拦截器,打开注解式鉴权功能 */@Overridepublic void addInterceptors(InterceptorRegistry registry) {// todo 注册注解拦截器 可以用来存放允许放行的路径// 除了/user/doLogin 可以放行  其余的操作都需要进行登录之后才可以进行操作registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/doLogin");}@Override
//  public void addInterceptors(InterceptorRegistry registry) {//      // 注册路由拦截器,自定义认证规则
//      registry.addInterceptor(new SaRouteInterceptor((req, res, handler)->{//          // 根据路由划分模块,不同模块不同鉴权
//          SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
//          SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
//          SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
//          SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
//          SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
//          SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
//      })).addPathPatterns("/**");
//  }
}

6.技术点

1.自定义token类型

token-style=simple-uuid

2.同端互斥登录 指定客户端登录与退出

StpUtil.login(2345, “PC”);

StpUtil.logout(2345, “PC”);

3.密码加密

SaSecureUtil.md5(“123456”);

SaSecureUtil.md5BySalt(“123456”, “salt”);

4.全局监听器

/*** 自定义侦听器的实现 */
@Component
public class MySaTokenListener implements SaTokenListener {/** 每次登录时触发 */@Overridepublic void doLogin(String loginType, Object loginId, SaLoginModel loginModel) {// ... }/** 每次注销时触发 */@Overridepublic void doLogout(String loginType, Object loginId, String tokenValue) {// ... }/** 每次被顶下线时触发 */@Overridepublic void doReplaced(String loginType, Object loginId, String tokenValue) {// ... }...}

5.与jwt继承

引入依赖

<!-- Sa-Token 整合 jwt -->
<dependency><groupId>cn.dev33</groupId><artifactId>sa-token-jwt</artifactId><version>1.29.0</version>
</dependency>

配置

sa-token:# jwt秘钥 jwt-secret-key: 456789123asdfghjk

注入指定Token方式

@Configuration
public class SaTokenConfigure {// Sa-Token 整合 jwt (Style模式)@Beanpublic StpLogic getStpLogicJwt() {return new StpLogicJwtForStyle();}
}

saToekn官网文档: https://sa-token.dev33.cn/doc/index.html#/

SaToken技术分享文档相关推荐

  1. 【海云捷迅云课堂】DPDK技术分享文档

    海云捷迅云课堂专题,旨在秉承开源理念,为大家提供OpenStack技术原理与实践经验,该专题文章均由海云捷迅工程师理论与实践相结合总结而成,如大家有其他想要了解的信息,可留言给我们,我们会根据问题酌情 ...

  2. 一份完整齐全的技术方案文档

    2022年-[归一计划三期-用户中心三期第二阶段]技术方案 部门:基础架构部 时间:2022.02.25 1.背景 描述技术方案的背景 由于历史原因,旧服务存在很多代码不规范.冗余度高.扩展性差等问题 ...

  3. 如何更安全的分享文档(权限设置、密码保护等功能)

    如何更安全的分享文档(权限设置.密码保护等功能) 桌面单机版文档 桌面单机版演示文稿 桌面单机版表格 桌面单机版表单 虽然在之前的旧版本ONLYOFFICE里面就已经有了文档的权限设置保护等功能了,但 ...

  4. 计算机文档设置,电脑这样设置快速的共享文件、分享文档!

    原标题:电脑这样设置快速的共享文件.分享文档! 在日常办公的时候,有时需要共同使用一些文件或者文档或者一些视频资料.那么要怎么方便的使用这些共同的资源呢?当然这时大家可能会说可以用QQ.微信传给对方不 ...

  5. 使用DOM技术操纵文档

    java 代码 [资料]JS使用DOM技术操纵文档 -- 创亿无限|创意无限|创意| -- 编程爱好者BLOG JavaScript高级应用:使用DOM技术操纵文档 我们知道,如果使用DHTML对象模 ...

  6. OCR技术识别文档的技术

    OCR技术识别文档的概括 我们常说的OCR.文字识别.OCR技术识别文档是指通过电子设备等将纸质上的文字识别出来,形成可编辑的文字. OCR技术识别文档的流程 随着扫描仪的普及与广泛应用,再加上摄像头 ...

  7. [转载]JBoss技术支持文档

    JBoss技术支持文档 1.本节内容简介 本章主要介绍JBOSS(免费的EJB服务器),以及教会大家如何安装Jboss,建立你第一个EJB和客户端.关于什么是EJB,以及如何开发等.这些关于EJB方面 ...

  8. Redis+Nginx+设计模式+Spring全家桶+Dubbo阿里P8技术精选文档

    最近花了很长的时间去搜罗Java核心技术好文,我把每个Java核心技术的优选文章都整理成了一个又一个的文档.昨天也是终于全部整理好了,今天就把这些东西分享给老铁们,也能为老铁们省去不少麻烦,想学什么技 ...

  9. Redis+Nginx+设计模式+Spring全家桶+Dubbo+阿里P7技术精选文档

    最近有一些粉丝私聊我,有没有技术文档,然后我这边经过一段时间收集,终于整理好了这套技术文档,里面包含了Redis.Nginx.设计模式.spring全家桶.Dubbo等关于Java架构方面的资料,一并 ...

最新文章

  1. chrome浏览器的跨域设置 Google Chrome浏览器下开启禁用缓存和js跨域限制--disable-web-security...
  2. 一文看透 Redis 分布式锁进化史(解读 + 缺陷分析)
  3. IIS问题:Server Application Error 的解决
  4. confluence创建页面加载缓慢_树莓派4B使用docker安装confluence
  5. 因“5毛钱”惹众怒的丰巢:我错了,下次还敢
  6. php 解决跨域问题
  7. matlab模拟化学反应,Matlab环境下化学反应动力学的MonteCarlo模拟
  8. 深度学习基础--输出层的神经元数应该与分类数匹配(分类数大于等于2)则是一个监督学习任务,对吗?
  9. div上下切换(新增、删除、上下div切换)
  10. 苹果WWDC将于6月8日夏季发布会苹果WWDC发布会直播地址
  11. web端用canvas把航拍图片实际场景渲染在高德卫星地图上面
  12. PII欧洲已经强制执行了,中国还会远吗?
  13. js 对象合并 与数组合并
  14. CSS3基础入门03
  15. Java Web应用开发——作业一
  16. 【笔记】js根据给定两点经纬度,计算距离
  17. 新装Ubuntu配置及部分软件安装
  18. flash 场景转换问题
  19. JavaScript常用数组API(2)
  20. 从HTML文件中抽取正文的简单方案

热门文章

  1. networkx教程
  2. 随心所欲大小写转换自定义函数
  3. 【笔记】取模运算的用法
  4. bootloader的作用
  5. 指纹识别综述(2): 指纹传感器
  6. persepolis download manager中文版(pdm下载器)
  7. AICS188-Project6-Q1-Q3
  8. RK3588(自带NPU)的环境搭建和体验(一)
  9. 产品架构图到底是怎么“画”出来的?
  10. 老毛桃怎样查看计算机桌面文件,桌面上的文件在PE里怎么找-win7在pe下的桌面文件,win7在pe下的桌面文件不见了...