项目集成sa-token

发布于:2025-07-03 ⋅ 阅读:(24) ⋅ 点赞:(0)

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续期就实现了!!


网站公告

今日签到

点亮在社区的每一天
去签到