【Sa-Token】学习笔记 03 - 认识Sa-Token中常见类
文章目录
前言
一、StpUtil
二、SaSession
三、SaTokenDao
四、SaStategy
五、SaManager
六、SaHolder
七、SaRouter
八、SaFoxUtil
九、SaTokenConfigFactory
十、SpringMVCUtil
十一、SaReactorHolder&SaReactorSyncHolder
前言
前面我们一家讲解了Sa-Token的一些源码分析,这一期我们来看看Sa-Token常见的一些类,干什
么的以及这些类有什么作用。
一、StpUtil
StpUtil:权限认证工具类,是我们最最最常用的一个工具类,他位于sa-token-core模块中的
cn.dev33.satoken.stp包中,他里面所有的方法都是静态的,主要调用StpLoginc里面的方法,你可
以理解StpUtil接收请求,逻辑都在StpLogic中,里面有大量工具方法,不仅可以用来login,还可
以鉴权【角色字符串和权限字符串】、注销、踢人下线、查询当前会话、获取会话对象
SaSession、获取token相关信息、id反查token、封禁账号、模拟任意身份、二级认证。总而言
之,该工具类几乎和sa-token框架的每个地方都能触发一点关系,可视为枢纽。
/**
* Sa-Token 权限认证工具类
*
* @author click33
* @since 1.0.0
*/
public class StpUtil {
private StpUtil() {}
/**
* 多账号体系下的类型标识
*/
public static final String TYPE = "login";
/**
* 底层使用的 StpLogic 对象
*/
public static StpLogic stpLogic = new StpLogic(TYPE);
/**
* 获取当前 StpLogic 的账号类型
*
* @return /
*/
public static String getLoginType(){
return stpLogic.getLoginType();
}
/**
* 安全的重置 StpLogic 对象
*
* <br> 1、更改此账户的 StpLogic 对象
* <br> 2、put 到全局 StpLogic 集合中
* <br> 3、发送日志
*
* @param newStpLogic /
*/
public static void setStpLogic(StpLogic newStpLogic) {
// 1、重置此账户的 StpLogic 对象
stpLogic = newStpLogic;
// 2、添加到全局 StpLogic 集合中
// 以便可以通过 SaManager.getStpLogic(type) 的方式来全局获取到这个 StpLogic
SaManager.putStpLogic(newStpLogic);
// 3、$$ 发布事件:更新了 stpLogic 对象
SaTokenEventCenter.doSetStpLogic(stpLogic);
}
.................省略
二、SaSession
SaSession:会话对象,你理解为我跟你的会话,你可以在会话中存一些数据或者取一些数据,专
业数据缓存组件,可以set、get各种键值。
在Sa-Token中,SaSession分为三种,分别是:
- Account-Session:指的是框架为每个账号分配的Session。
- Token-Session:指的是框架为每个token分配的SaSession。
- Custom-Session:指的是以一个特定的值作为SessionId,来分配Session。
注意:以上分类仅为框架设计层面的概念区分,实际他们的数据存储格式都是一致的。
type来区分不同类型的SaSession。
<!-- Sa-Token 整合 RedisTemplate -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-template</artifactId>
<version>1.41.0</version>
</dependency>
<!-- 提供 Redis 连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
三、SaTokenDao
SaSession作为会话对象,而SaTokenDao则是作为数据持久层接口,负责所有会话数据底层的读
写,SaTokenDao接口有个默认的实现SaTokenDaoDefaultImpl,如果只引入sa-token依赖,用的
就是这个默认实现,默认将会话的数据存储在内存当中,用的是ConcurrentHashMap存储会话数
据,但是我们在开发中都不会将会话数据存储在内存当中,因为重启后数据就会丢失,一般都会存
储在Redis、MySQL当中,Sa-Token也提供了集成Redis依赖,只需要引入依赖,那么会话的数据
就可以存储在Redis当中。
<!-- Sa-Token 整合 RedisTemplate -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-template</artifactId>
<version>1.41.0</version>
</dependency>
<!-- 提供 Redis 连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
四、SaStategy
SaStategy-全局策略,该类写一些全局策略,如创建Token的策略、创建Session的策略等。所有
策略可自定义。
/**
* 创建 Token 的策略
* <p> 参数 [账号id, 账号类型]
*/
public BiFunction<Object, String, String> createToken = (loginId, loginType) -> {
// 默认,还是uuid
return "xxxxx-xxxxx-xxxxx-xxxxx";
};
/**
* 创建 Session 的策略
* <p> 参数 [SessionId]
*/
public Function<String, SaSession> createSession = (sessionId) -> {
return new SaSession(sessionId);
};
/**
* 判断:集合中是否包含指定元素(模糊匹配)
* <p> 参数 [集合, 元素]
*/
public BiFunction<List<String>, String, Boolean> hasElement = (list, element) -> {
return false;
};
/**
* 对一个 [Method] 对象进行注解校验 (注解鉴权内部实现)
* <p> 参数 [Method句柄]
*/
public Consumer<Method> checkMethodAnnotation = (method) -> {
// ...
};
/**
* 对一个 [元素] 对象进行注解校验 (注解鉴权内部实现)
* <p> 参数 [element元素]
*/
public Consumer<AnnotatedElement> checkElementAnnotation = (target) -> {
// ...
};
/**
* 从元素上获取注解(注解鉴权内部实现)
* <p> 参数 [element元素,要获取的注解类型]
*/
public BiFunction<AnnotatedElement, Class<? extends Annotation> , Annotation> getAnnotation = (element, annotationClass)->{
// 默认使用jdk的注解处理器
return element.getAnnotation(annotationClass);
};
/**
* 拼接两个url
* <p> 例如:url1=http://domain.cn,url2=/sso/auth,则返回:http://domain.cn/sso/auth
* <p> 参数 [第一个url, 第二个url]
*/
public BiFunction<String, String, String> spliceTwoUrl = (url1, url2) -> {
return xxx;
};
/**
* 是否自动续期,每次续期前都会执行,可以加入动态判断逻辑
* <p> 参数 当前 stpLogic 实例对象
* <p> 返回 true 自动续期 false 不自动续期
*/
public Function<StpLogic, Boolean> autoRenew = (stpLogic) -> {
return stpLogic.getConfigOrGlobal().getAutoRenew();
};
五、SaManager
SaManger是负责所有全局组件,管理所有Sa-Token的全局组件,通过这个类可以快速获取、写入
各种全局对象。
SaManager.getConfig(); // 获取全局配置对象
SaManager.getSaTokenDao(); // 获取数据持久化对象
SaManager.getStpInterface(); // 获取权限认证对象
SaManager.getSaTokenContext(); // 获取一级Context处理对象
SaManager.getSaTokenSecondContext(); // 获取二级Context处理对象
SaManager.getSaTokenContextOrSecond(); // 获取一个可用的 Context 处理对象
SaManager.getSaTokenListener(); // 获取侦听器对象
SaManager.getSaTemp(); // 获取临时令牌认证模块对象
SaManager.getSaJsonTemplate(); // 获取 JSON 转换器 Bean
SaManager.getSaSignTemplate(); // 获取参数签名 Bean
SaManager.getStpLogic("type"); // 获取指定账号类型的StpLogic对象,获取不到时自动创建并返回
SaManager.getStpLogic("type", false); // 获取指定账号类型的StpLogic对象,获取不到时抛出异常
SaManager.putStpLogic(stpLogic); // 向全局集合中 put 一个 StpLogic
挑选下面四个方法重点说明:
SaManger.getConfig() //获取全局配置对象
SaManger.getSaTokenDao() //获取数据持久化对象
SaManger.getStpInterface() //获取权限认证对象
SaManger.getSaTokenListener() //获取侦听器对象
六、SaHolder
Sa-Token上下文持有类,你可以通过此类快速获取当前环境下的SaRequest、SaResponse、
SaStorage、SaApplication对象。
SaHolder.getContext(); // 获取当前请求的 SaTokenContext
SaHolder.getRequest(); // 获取当前请求的 [Request] 对象
SaHolder.getResponse(); // 获取当前请求的 [Response] 对象
SaHolder.getStorage(); // 获取当前请求的 [Storage] 对象
SaHolder.getApplication(); // 获取全局 SaApplication 对象
七、SaRouter
路由匹配工具类。鉴权的时候会用到,提供一系列的路由匹配方法,一般在全局拦截器、过滤器做
路由拦截鉴权。
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,定义详细认证规则
registry.addInterceptor(new SaInterceptor(handler -> {
// 指定一条 match 规则
SaRouter
.match("/**") // 拦截的 path 列表,可以写多个 */
.notMatch("/user/doLogin") // 排除掉的 path 列表,可以写多个
.check(r -> StpUtil.checkLogin()); // 要执行的校验动作,可以写完整的 lambda 表达式
// 根据路由划分模块,不同模块不同鉴权
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("/**");
}
}
八、SaFoxUtil
Sa-Token内部工具类,包含一些工具方法:
SaFoxUtil.printSaToken(); // 打印 Sa-Token 版本字符画
SaFoxUtil.getRandomString(8); // 生成指定长度的随机字符串
SaFoxUtil.isEmpty(str); // 指定字符串是否为null或者空字符串
SaFoxUtil.isNotEmpty(str); // 指定字符串是否不是null或者空字符串
SaFoxUtil.equals(a, b); // 比较两个对象是否相等
SaFoxUtil.getMarking28(); // 以当前时间戳和随机int数字拼接一个随机字符串
SaFoxUtil.formatDate(date); // 将日期格式化为yyyy-MM-dd HH:mm:ss字符串
SaFoxUtil.searchList(dataList, prefix, keyword, start, size, sortType); // 从集合里查询数据
SaFoxUtil.searchList(dataList, start, size, sortType); // 从集合里查询数据
SaFoxUtil.vagueMatch(patt, str); // 字符串模糊匹配
SaFoxUtil.getValueByType(obj, cs); // 将指定值转化为指定类型
SaFoxUtil.joinParam(url, parameStr); // 在url上拼接上kv参数并返回
SaFoxUtil.joinParam(url, key, value); // 在url上拼接上kv参数并返回
SaFoxUtil.joinSharpParam(url, parameStr); // 在url上拼接锚参数
SaFoxUtil.joinSharpParam(url, key, value); // 在url上拼接锚参数
SaFoxUtil.arrayJoin(arr); // 将数组的所有元素使用逗号拼接在一起
SaFoxUtil.isUrl(str); // 使用正则表达式判断一个字符串是否为URL
SaFoxUtil.encodeUrl(str); // URL编码
SaFoxUtil.decoderUrl(str); // URL解码
SaFoxUtil.convertStringToList(str); // 将指定字符串按照逗号分隔符转化为字符串集合
SaFoxUtil.convertListToString(list); // 将指定集合按照逗号连接成一个字符串
SaFoxUtil.convertStringToArray(str); // String 转 Array,按照逗号切割
SaFoxUtil.convertArrayToString(arr); // Array 转 String,按照逗号切割
SaFoxUtil.emptyList(); // 返回一个空集合
SaFoxUtil.toList(... strs); // String 数组转集合
九、SaTokenConfigFactory
配置对象工厂类,用于手动读取配置文件初始化SaTokenConfig对象,只有在非IOC环境下你才会
用到此类,在SpringBoot中会已经将SaTokenConfig注入到我们IOC环境中,首先他会去拿
SaTokenConfig,如果拿不到才去走这个类创建SaTokenConfig。
十、SpringMVCUtil
SpringMVC操作的工具类,位于包:sa-token-spring-boot-starter
,我们一般很难用到该工具
类,几乎是框架在自己用。
SpringMVCUtil.getRequest(); // 获取本次请求的 request 对象
SpringMVCUtil.getResponse(); // 获取本次请求的 response 对象
SpringMVCUtil.isWeb(); // 判断当前是否处于 Web 上下文中
十一、SaReactorHolder&SaReactorSyncHolder
Sa-Token
集成Reactor
时的 ServerWebExchange
工具类,位于包:sa-token-reactor-spring-boot-
starter
,在最新流行的Web-Flux
中用到的一种模式Reactor
,当你用到Web-Flux
,那你可能需要关
注一下。
// 异步方式获取 ServerWebExchange 对象
SaReactorHolder.getContext().map(e -> {
System.out.println(e);
});
// 同步方式获取 ServerWebExchange 对象
ServerWebExchange e = SaReactorSyncHolder.getContext();
System.out.println(e);