Sa-Token

介绍

Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证权限认证单点登录OAuth2.0分布式Session会话微服务网关鉴权 等一系列权限相关问题。

Sa-Token 旨在以简单、优雅的方式完成系统的权限认证部分

官网:https://sa-token.cc

集成

  1. 导入依赖

    1
    2
    3
    4
    5
    6
    <!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
    <dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.45.0</version>
    </dependency>
    • 如果使用的 SpringBoot 3.x,请引入 sa-token-spring-boot3-starter
    • 如果使用的 SpringBoot 4.x,请引入 sa-token-spring-boot4-starter
  2. 添加配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    server:
    # 端口
    port: 8081

    # Sa-Token 配置
    sa-token:
    # token 名称(同时也是 cookie 名称)
    token-name: satoken
    # token 有效期(单位:秒) 默认30天,-1 代表永久有效
    timeout: 2592000
    # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
    active-timeout: -1
    # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
    is-concurrent: true
    # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
    is-share: false
    # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
    token-style: uuid
    # 是否输出操作日志
    is-log: true
  3. 创建Controller进行测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @RestController
    @RequestMapping("/user/")
    public class UserController {

    // 测试登录,浏览器访问: http://localhost:8081/user/doLogin?username=zhang&password=123456
    @RequestMapping("doLogin")
    public String doLogin(String username, String password) {
    // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
    if("zhang".equals(username) && "123456".equals(password)) {
    StpUtil.login(10001);
    return "登录成功";
    }
    return "登录失败";
    }

    // 查询登录状态,浏览器访问: http://localhost:8081/user/isLogin
    @RequestMapping("isLogin")
    public String isLogin() {
    return "当前会话是否登录:" + StpUtil.isLogin();
    }
    }

基本使用

登录

1
2
// 会话登录:参数填写要登录的账号id,建议的数据类型:long | int | String, 不可以传入复杂类型,如:User、Admin 等等
StpUtil.login(Object userId);

创建了一个 token 凭证,且通过 Cookie 上下文返回给了前端;

StpUtil已将token保存到cookie中,省略了手写返回 token 的代码

1
2
3
4
5
// 判断当前会话是否已经登录,返回 true=已登录,false=未登录
StpUtil.isLogin();

// 检验当前会话是否已经登录, 如果已登录代码会安全通过,未登录则抛出异常:`NotLoginException`
StpUtil.checkLogin();
1
2
3
4
5
// 当前会话注销登录
StpUtil.logout();

// 踢人下线
StpUtil.kickout();

注销:会将Token删除

踢人下线:Token不被删除,会被标记,下次使用会提示

鉴权

代码鉴权

  1. 先实现StpInterface接口来返回账号拥有的权限和角色

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    @Component
    public class StpInterfaceImpl implements StpInterface {

    /**
    * 返回一个账号所拥有的权限码集合
    */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
    // 本 list 仅做模拟,实际项目中要根据具体业务逻辑来查询权限
    List<String> list = new ArrayList<>();

    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<>();

    list.add("admin");
    list.add("super-admin");

    return list;
    }

    }
  2. 使用,校验角色和权限

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 获取:当前账号所拥有的权限集合
    StpUtil.getPermissionList();

    // 判断:当前账号是否含有指定权限, 返回 true 或 false
    StpUtil.hasPermission("user.add");

    // 校验:当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException
    StpUtil.checkPermission("user.add");

    // 校验:当前账号是否含有指定权限 [指定多个,必须全部验证通过]
    StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");

    // 校验:当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
    StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");

注解鉴权

  1. 注册拦截器,开启注解鉴权功能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Configuration
    public class SaTokenConfigure implements WebMvcConfigurer {

    // 注册 Sa-Token 拦截器,打开注解式鉴权功能
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    // 注册 Sa-Token 拦截器,打开注解式鉴权功能
    registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }
    }
  2. 使用(只能在Controller层使用)

    • @SaCheckLogin: 登录校验 —— 只有登录之后才能进入该方法。
    • @SaCheckRole("admin"): 角色校验 —— 必须具有指定角色标识才能进入该方法。
    • @SaCheckPermission("user:add"): 权限校验 —— 必须具有指定权限才能进入该方法。
    • @SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法。
    • @SaCheckHttpBasic: HttpBasic校验 —— 只有通过 HttpBasic 认证后才能进入该方法。
    • @SaCheckHttpDigest: HttpDigest校验 —— 只有通过 HttpDigest 认证后才能进入该方法。
    • @SaCheckDisable("comment"):账号服务封禁校验 —— 校验当前账号指定服务是否被封禁。
    • @SaCheckSign:API 签名校验 —— 用于跨系统的 API 签名参数校验。
    • @SaIgnore:忽略校验 —— 表示被修饰的方法或类无需进行注解鉴权和路由拦截器鉴权

    如果需要再Controller以外的层使用,需要引入依赖sa-token-spring-aop,不可同时用拦截器和AOP,否则会触发两次

拦截器鉴权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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("/**");
}
}

Session

通过 Session 我们可以很方便的缓存一些高频读写数据

  • Account-Session: 指的是框架为每个 账号id 分配的 Session
  • Token-Session: 指的是框架为每个 token 分配的 Session
  • Custom-Session: 指的是以一个 特定的值 作为SessionId,来分配的 Session
1
2
3
4
5
// 在登录时缓存 user 对象 
StpUtil.getSession().set("user", user);

// 然后我们就可以在任意处使用这个 user 对象
SysUser user = (SysUser) StpUtil.getSession().get("user");

Sa-Token
http://xwww12.github.io/2026/07/14/后端/Sa-Token/
作者
xw
发布于
2026年7月14日
许可协议