1、sa-token介绍
Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。
官网地址:
https://sa-token.cc/doc.html
2、sa-token与spring security比较
(1)易用性
Spring Security 可能需要一定的学习曲线,因为它提供了大量的功能并且可以通过多种方式进行配置。
sa-token 相对简单,易于理解和实现,尤其是在简单的应用场景下。
(2)性能考虑
Spring Security 在某些情况下可能会引入一些性能开销,尤其是在高度定制的情况下。
sa-token 通常具有较好的性能,因为它的无状态特性减少了服务器端的状态维护。
3、sa-token使用
(1)引入依赖
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>按需引入对应版本</version>
</dependency>
(2)添加基础配置
sa-token:
token-name: Satoken # token名字
timeout: 7200 # token超时时间
is-concurrent: false # 当前端有多个域时,是否允许多个域同时登录
is-share: true #当前端有多个域时,需要设置为true
token-style: uuid # token风格
is-log: false # 是否输出日志
auto-renew: true # 设置令牌(token)自动续期功能为开启状态
active-timeout: 1800 # 配置令牌在失效前的有效时间为1800秒。
(3)添加拦截器配置
@Component
public class SaTokenInitConfig implements CommandLineRunner, WebMvcConfigurer {
@Override
public void run(String... args) throws Exception {
// 初始化 SaToken
SaManager.getConfig().setTokenName("Satoken");
SaManager.getConfig().setTimeout(7200);
}
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,定义详细认证规则
registry.addInterceptor(new SaInterceptor(handle -> {
StpUtil.checkLogin();
if(StpUtil.isLogin()){
// 写一些登录后公共逻辑
}
}))
.addPathPatterns("/**")
.excludePathPatterns("/login");
}
}
(4)编写全局异常处理
注意:因为sa-token当校验失败后,就直接抛异常的,不会处理异常,若要处理校验结果,需要编写全局异常处理器处理对应的异常
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 全局异常拦截
@ExceptionHandler(NotRoleException.class)
public SaResult notRoleException(NotRoleException e) {
return SaResult.error(e.getMessage());
}
@ExceptionHandler(NotLoginException.class)
public SaResult handlerException(NotLoginException e) {
SaResult saResult = SaResult.get(401, "请登录", null);
return saResult;
}
}
完成上面的配置对于单体项目来说就可以使用sa-token完成各种功能实现了
4、sa-token权限控制
(1)常见注解
- @SaCheckLogin: 登录校验 —— 只有登录之后才能进入该方法。
- @SaCheckRole(“admin”): 角色校验 —— 必须具有指定角色标识才能进入该方法。
- @SaCheckPermission(“user:add”): 权限校验 —— 必须具有指定权限才能进入该方法。
- @SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法。
- @SaCheckHttpBasic: HttpBasic校验 —— 只有通过 HttpBasic 认证后才能进入该方法。
- @SaCheckHttpDigest: HttpDigest校验 —— 只有通过 HttpDigest 认证后才能进入该方法。
- @SaIgnore:忽略校验 —— 表示被修饰的方法或类无需进行注解鉴权和路由拦截器鉴权。
- @SaCheckDisable(“comment”):账号服务封禁校验 —— 校验当前账号指定服务是否被封禁。
eg:
控制接口只能拥有user角色的用户才能请求
@GetMapping("/test02")
@SaCheckRole("user")
public String test02() {
return "sdsad";
}
但注意若要实现接口权限控制,我们需要自己编写一个接口的权限控制实现类
// 保证此类被 SpringBoot 扫描,完成 Sa-Token 的自定义权限验证扩展
@Component
public class StpInterfaceImpl implements StpInterface {
/**
* 返回一个账号所拥有的权限码集合
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
// 本 list 仅做模拟,实际项目中要根据具体业务逻辑来查询权限
List<String> list = new ArrayList<String>();
list.add("101");
list.add("user.add");
list.add("user.update");
list.add("user.get");
// list.add("user.delete");
list.add("art.*");
return list;
}
/**
* 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
// 本 list 仅做模拟,实际项目中要根据具体业务逻辑来查询角色
List<String> list = new ArrayList<String>();
list.add("user");
list.add("super-admin");
return list;
}
5、分布式环境下sa-token使用
因为sa-token有个缺点就是他会将token存储在缓存中,当宕机或重启token就会丢失,但对于这问题sa-token也提供了解决方式,就是集成各种优秀的第三方缓存工具进行分布式缓存
eg:redis
(1)引入依赖
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis</artifactId>
<version>1.38.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.12.0</version>
</dependency>
坑点:注意redis与缓存池的版本对应,不是会报错
(2)添加redis基础配置
spring:
data:
redis:
database: 2
host: 127.0.0.1
port: 6379
timeout: 10s
lettuce:
pool:
max-active: 200
max-wait: -1ms
max-idle: 10
min-idle: 0
完成以上操作基本就完成了,但可能有些小伙伴觉得sa-token这是怎么将token信息存储到redis?会自动存储?
答案:框架会自动帮忙存储的,若想知道原理,可以自己去看源码
https://gitee.com/dromara/sa-token
当登录后: