Sa-Token 集成 jwt

Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证、权限认证、单点登录、OAuth2、微服务网关鉴权 等一系列权限相关问题。

Gitee 开源地址:https://gitee.com/dromara/sa-token

很多小伙伴关心的一个话题,那就是 Sa-Token 和 JWT 哪个更好用一些,其实不用纠结这个问题,Sa-Token 提供了 sa-token-jwt 插件,
可以将 Sa-Token 和 jwt 结合起来,这样我们就可以既有 Sa-Token 进行方便的鉴权,又可以得到 jwt 的 Token 扩展参数能力了。

下面我将介绍如何在 Sa-Token 中方便的集成 jwt。

一、引入依赖

首先在项目 pom.xml 中引入:

<!-- SpringBoot 集成 Sa-Token -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

<!-- Sa-Token 整合 jwt -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-jwt</artifactId>
    <version>1.34.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Gradle 方式:

// SpringBoot 集成 Sa-Token
implementation 'cn.dev33:sa-token-spring-boot-starter:1.34.0'

// Sa-Token 整合 jwt
implementation 'cn.dev33:sa-token-jwt:1.34.0'
  • 1
  • 2
  • 3
  • 4
  • 5

注意: sa-token-jwt 显式依赖 hutool-jwt 5.7.14 版本,意味着:你的项目中要么不引入 Hutool,要么引入版本 >= 5.7.14 的 Hutool 版本

二、配置秘钥

application.yml 配置文件中配置 jwt 生成秘钥:

sa-token:
    # jwt秘钥 
    jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk
  • 1
  • 2
  • 3

注:为了安全起见请不要直接复制官网示例这个字符串(随便按几个字符就好了)

三、注入jwt实现

根据不同的整合规则,插件提供了三种不同的模式,你需要 选择其中一种 注入到你的项目中

Simple 简单模式:Token 风格替换

@Configuration
public class SaTokenConfigure {
    // Sa-Token 整合 jwt (Simple 简单模式)
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForSimple();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Mixin 混入模式:混入部分逻辑

@Configuration
public class SaTokenConfigure {
    // Sa-Token 整合 jwt (Mixin 混入模式)
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForMixin();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Stateless 无状态模式:服务器完全无状态

@Configuration
public class SaTokenConfigure {
    // Sa-Token 整合 jwt (Stateless 无状态模式)
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForStateless();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

四、开始使用

然后我们就可以像之前一样使用 Sa-Token 了

/**
 * 登录测试 
 */
@RestController
@RequestMapping("/acc/")
public class LoginController {

    // 测试登录
    @RequestMapping("login")
    public SaResult login() {
        StpUtil.login(10001);
        return SaResult.ok("登录成功");
    }

    // 查询登录状态
    @RequestMapping("isLogin")
    public SaResult isLogin() {
        return SaResult.ok("是否登录:" + StpUtil.isLogin());
    }

    // 测试注销
    @RequestMapping("logout")
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok();
    }

}
  • 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

访问上述接口,观察Token生成的样式

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbklkIjoiMTAwMDEiLCJybiI6IjZYYzgySzBHVWV3Uk5NTTl1dFdjbnpFZFZHTVNYd3JOIn0.F_7fbHsFsDZmckHlGDaBuwDotZwAjZ0HB14DRujQfOQ
  • 1

五、不同模式策略对比

注入不同模式会让框架具有不同的行为策略,以下是三种模式的差异点(为方便叙述,以下比较以同时引入 jwt 与 Redis 作为前提):

功能点 Simple 简单模式 Mixin 混入模式 Stateless 无状态模式
Token风格 jwt风格 jwt风格 jwt风格
登录数据存储 Redis中存储 Token中存储 Token中存储
Session存储 Redis中存储 Redis中存储 无Session
注销下线 前后端双清数据 前后端双清数据 前端清除数据
踢人下线API 支持 不支持 不支持
顶人下线API 支持 不支持 不支持
登录认证 支持 支持 支持
角色认证 支持 支持 支持
权限认证 支持 支持 支持
timeout 有效期 支持 支持 支持
activity-timeout 有效期 支持 支持 不支持
id反查Token 支持 支持 不支持
会话管理 支持 部分支持 不支持
注解鉴权 支持 支持 支持
路由拦截鉴权 支持 支持 支持
账号封禁 支持 支持 不支持
身份切换 支持 支持 支持
二级认证 支持 支持 支持
模式总结 Token风格替换 jwt 与 Redis 逻辑混合 完全舍弃Redis,只用jwt

六、扩展参数

你可以通过以下方式在登录时注入扩展参数:

// 登录10001账号,并为生成的 Token 追加扩展参数name
StpUtil.login(10001, SaLoginConfig.setExtra("name", "zhangsan"));

// 连缀写法追加多个
StpUtil.login(10001, SaLoginConfig
                .setExtra("name", "zhangsan")
                .setExtra("age", 18)
                .setExtra("role", "超级管理员"));

// 获取扩展参数 
String name = StpUtil.getExtra("name");

// 获取任意 Token 的扩展参数 
String name = StpUtil.getExtra("tokenValue", "name");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

七、在多账户模式中集成 jwt

sa-token-jwt 插件默认只为 StpUtil 注入 StpLogicJwtFoxXxx 实现,自定义的 StpUserUtil 是不会自动注入的,我们需要帮其手动注入:

/**
 * 为 StpUserUtil 注入 StpLogicJwt 实现 
 */
@Autowired
public void setUserStpLogic() {
    StpUserUtil.setStpLogic(new StpLogicJwtForSimple(StpUserUtil.TYPE));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

八、自定义 SaJwtUtil 生成 token 的算法

如果需要自定义生成 token 的算法(例如更换sign方式),直接重写 SaJwtTemplate 对象即可:

/**
 * 自定义 SaJwtUtil 生成 token 的算法 
 */
@Autowired
public void setSaJwtTemplate() {
    SaJwtUtil.setSaJwtTemplate(new SaJwtTemplate() {
        @Override
        public String generateToken(JWT jwt, String keyt) {
            System.out.println("------ 自定义了 token 生成算法");
            return super.generateToken(jwt, keyt);
        }
    });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

九、注意点

1、使用 jwt-simple 模式后,is-share=false 恒等于 false。

is-share=true 的意思是每次登录都产生一样的 token,这种策略和 [ 为每个 token 单独设定 setExtra 数据 ] 不兼容的,
为保证正确设定 Extra 数据,当使用 jwt-simple 模式后,is-share 配置项 恒等于 false

2、使用 jwt-mixin 模式后,is-concurrent 必须为 true。

is-concurrent=false 代表每次登录都把旧登录顶下线,但是 jwt-mixin 模式登录的 token 并不会记录在持久库数据中,
技术上来讲无法将其踢下线,所以此时顶人下线和踢人下线等 API 都属于不可用状态,所以此时 is-concurrent 配置项必须配置为 true


参考资料

← Sa-Token 多账号认证:同时为系统的 Admin 账号和 User 账号提供鉴权操作 SpringBoot 使用 Sa-Token 完成权限认证 →

当前博客已开放版权,所有人均可免费转载,无需联系 Sa-Token 团队获取授权。只需要在转载时保留底部 Sa-Token 官网链接 + 开源仓库链接即可。

Copyright ©2026 Sa-Token java 权限认证 | sa-token.com | 鲁ICP备18046274号-5 | 鲁公网安备37011202002956号