sa-token简介
sa-token 是一个基于 Java 的轻量级权限认证框架,主要用于实现系统的登录认证、权限控制、Token 管理等功能。它简单易用、功能强大,适用于 Spring Boot、微服务架构等多种项目场景。
主要特性
1.登录认证
1.1.支持登录状态的保持与验证。
1.2.提供 Token 生成、校验机制,支持自定义 Token 规则。
2.权限控制
2.1.支持接口级别的权限验证。
2.2.可以通过注解方式快速实现方法级别的权限控制(如 @SaCheckPermission)。
3.多账户体系
3.1.支持多种账号类型,例如用户账号、管理员账号等。
3.2.不同账号体系之间相互隔离,互不影响。
4.会话管理
4.1.支持踢下线、强制退出等功能。
4.2.提供在线会话列表查询能力。
5.集成简单
5.1.与 Spring Boot 无缝集成,配置简单。
5.2.提供丰富的文档和示例代码。
6.分布式支持
6.1.支持在分布式系统中使用 Redis 实现 Token 共享。
6.2.提供集群部署下的统一鉴权能力。
7.扩展性强
7.1.提供拦截器、监听器等扩展点,便于定制化开发。
常用注解
@SaCheckLogin:用于校验用户是否已登录,标注在控制器方法或类上,未登录用户访问时会抛出异常。
@SaCheckPermission("permission"):校验当前用户是否拥有指定权限(permission),支持多个权限组合判断:
@SaCheckPermission("user.add"):必须具有 user.add 权限。
@SaCheckPermission(value = {"user.add", "user.delete"}, mode = SaMode.OR):满足其中一个权限即可。
@SaCheckPermission(value = {"user.add", "user.delete"}, mode = SaMode.AND):必须同时满足所有权限。
@SaCheckRole("role"):校验用户是否有指定角色。
@SaCheckRole("admin"):必须是 admin 角色。
@SaCheckRole(value = {"admin", "manager"}, mode = SaMode.OR):满足其中一个角色即可。
@SaIgnore:忽略所有 sa-token 的注解校验,适用于公开接口,无需登录即可访问。
使用场景
后台管理系统中的权限控制。
微服务架构中的统一鉴权。
多终端(Web、App、小程序)统一登录态管理。
引入依赖
<!-- 权限框架 Sa-Token -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>1.38.0</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>1.38.0</version>
</dependency>
<!-- Redis 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
yml文件里面配置好redis连接
data: redis: host: localhost
# 我的redis是没有设置密码的 password:
创建sa-token配置类(这里只创建了拦截器)
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
/**
* 注册 Sa-Token 拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaInterceptor())
// 拦截所有路径
.addPathPatterns("/**")
// 放行登录接口
.excludePathPatterns("/login");
}
}
controller打上注解
测试一下
成功被拦截!!
现在有一个问题,如果token有效期设置为30分钟,用户如果在还在使用这时候token过期了那么就会跳到登录页,用户正在填的东西就没有了,这样用户体验有点差,我们可以搞个token续期,就是用户发出请求就将token有效期设置为30分钟,这样的话只有30分钟无操作token才会过期
在配置类中添加以下配置
private static final String TOKEN_NAME = "token"; private static final Integer TIMEOUT = 1800; private static final Integer ACTIVITY_TIMEOUT = 1800; private static final String TOKEN_STYLE = "uuid"; @Bean @Primary public SaTokenConfig saTokenConfig() { SaTokenConfig saTokenConfig = new SaTokenConfig(); // token名称 (同时也是cookie名称) saTokenConfig.setTokenName(TOKEN_NAME); // token有效期,单位s 默认30天, -1代表永不过期 saTokenConfig.setTimeout(TIMEOUT); // token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 saTokenConfig.setActiveTimeout(ACTIVITY_TIMEOUT); // 是否允许同一账号并发登录 saTokenConfig.setIsConcurrent(true); // 在多人登录同一账号时,是否共用一个token saTokenConfig.setIsShare(true); // token风格 saTokenConfig.setTokenStyle(TOKEN_STYLE); // 开启自动续期 saTokenConfig.setAutoRenew(true); return saTokenConfig; } 修改拦截器
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SaInterceptor(handle ->{ // 判断是否登录 StpUtil.checkLogin(); // 刷新token有效期 if (StpUtil.isLogin()){ StpUtil.renewTimeout(TIMEOUT); } })) // 拦截所有路径 .addPathPatterns("/**") // 放行登录接口 .excludePathPatterns("/login"); }
测试一下
这是之前的
这是请求以后的
token续期就实现了!!