夜雨聆风学习资料网

ARTICLE · 1138315

下篇 | Sa-Token认证框架,源码分析、简易SSO、SaaS多租户、快速上手!选型对比!

下篇 | Sa-Token认证框架,源码分析、简易SSO、SaaS多租户、快速上手!选型对比!

一个国产轻量级认证框架,能否替代 Spring Security?小 A 决定亲自探究。本文基于 Sa-Token  1.39.0 版本探究!

标签:轻量级、认证、单点登录、二级认证

注:此文为下篇



8. 分场景讨论

8.1 前后端分离:JWT + 无状态

在前后端分离场景中,前端(Vue/React)与后端独立部署,Token 通常通过请求头传递。

sa-token:  token-name: Authorization  is-read-cookie: false  is-read-header: true  # Token 前缀(可选,类似 Bearer)  token-prefix: "Bearer"
@Configurationpublic class CorsConfig implements WebMvcConfigurer {    @Override    public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("/**")            .allowedOriginPatterns("*")            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")            .allowedHeaders("*")            .allowCredentials(true)            .maxAge(3600);    }}@Configurationpublic class SaTokenConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))            .addPathPatterns("/**")            .excludePathPatterns("/auth/login", "/auth/register", "/swagger-ui/**", "/v3/api-docs/**");    }}

前端请求示例(JavaScript):

// 登录后保存 TokenlocalStorage.setItem('satoken', response.data.token);// 请求时携带 Tokenaxios.get('/api/user/list', {    headers: {        'Authorization': localStorage.getItem('satoken')    }});

JWT 模式:

Sa-Token 也支持 JWT 模式,将用户信息直接编码到 Token 中,实现无状态认证。

<dependency>    <groupId>cn.dev33</groupId>    <artifactId>sa-token-jwt</artifactId>    <version>1.39.0</version></dependency>
// 配置 JWT 模式Sa-TokenConfigure configure = new Sa-TokenConfigure()    .setTokenStyle("jwt");

有状态 vs 无状态:

维度
有状态(Redis 存储)
无状态(JWT)
Token 大小
小(仅 UUID)
较大(包含用户信息)
服务端存储
Redis 存储
无存储
登出方式
删除 Redis 数据
无法主动失效(需黑名单)
用户信息更新
实时更新
需重新签发
分布式支持
天然支持
天然支持
安全性
Token 泄露可服务端撤销
Token 泄露无法撤销
适用场景
多数业务系统
API 网关、微服务

8.2 移动端 APP:多端独立

移动端场景下,用户可能在手机、平板、PC 等多个设备上登录,Sa-Token 的多端独立模式非常适合。

sa-token:  is-concurrent: true  is-share: false  token-style: uuid
@RestController@RequestMapping("/app/auth")public class AppAuthController {    @PostMapping("/login")    public Result<String> login(@RequestParam String username,                                @RequestParam String password,                                @RequestParam(defaultValue = "Mobile") String device) {        User user = userService.login(username, password);        if (user == null) {            return Result.error("登录失败");        }        // 指定设备类型登录        StpUtil.login(user.getId(), device);        return Result.success(StpUtil.getTokenValue());    }    @PostMapping("/switch-device")    public Result<String> switchDevice(@RequestParam String device) {        // 切换到指定设备        StpUtil.switchDevice(device);        return Result.success(StpUtil.getTokenValue());    }}

8.3 管理后台:角色 + 权限

管理后台通常需要精细的权限控制,Sa-Token 提供了完善的 RBAC(Role-Based Access Control)支持。

@Servicepublic class AuthServiceImpl implements AuthService {    @Override    public void setPermission(Long userId) {        List<String> permissions = permissionMapper.selectByUserId(userId);        StpUtil.getSession().set("permission", permissions);    }    @Override    public List<String> getPermissionList(Object loginId) {        return StpUtil.getSessionByLoginId(loginId).get("permission", List.class);    }    @Override    public void setRole(Long userId) {        List<String> roles = roleMapper.selectByUserId(userId);        StpUtil.getSession().set("role", roles);    }}

数据模型设计:

  +-----------+       +---------------+       +-----------+  |   User    |       |  User_Role    |       |   Role    |  +-----------+       +---------------+       +-----------+  | id        |<----->| user_id       |       | id        |  | username  |       | role_id       |<----->| role_key  |  | password  |       +---------------+       | role_name |  +-----------+                               +-----------+                                                    |                                              +---------------+                                              | Role_Permission|                                              +---------------+                                              | role_id       |                                              | permission_id |                                              +---------------+                                                    |                                              +-----------+                                              |Permission |                                              +-----------+                                              | id        |                                              | perm_key  |                                              | perm_name |                                              +-----------+

8.4 SaaS 多租户:多账号体系

SaaS 应用通常需要支持多租户隔离,每个租户有独立的用户体系和管理员体系。

// 租户级别的账号体系public class TenantStpLogic {    private final String tenantId;    private final StpLogic stpLogic;    public TenantStpLogic(String tenantId) {        this.tenantId = tenantId;        this.stpLogic = new StpLogic("tenant:" + tenantId);    }    public void login(Object id) {        stpLogic.login(id);    }    public boolean isLogin() {        return stpLogic.isLogin();    }    public Object getLoginId() {        return stpLogic.getLoginId();    }}
@Componentpublic class TenantContext {    private static final ThreadLocal<String> CURRENT_TENANT = new ThreadLocal<>();    public static void setTenantId(String tenantId) {        CURRENT_TENANT.set(tenantId);    }    public static String getTenantId() {        return CURRENT_TENANT.get();    }    public static void clear() {        CURRENT_TENANT.remove();    }}// 拦截器中提取租户信息public class TenantInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request,                            HttpServletResponse response,                            Object handler) {        String tenantId = request.getHeader("X-Tenant-Id");        TenantContext.setTenantId(tenantId);        return true;    }    @Override    public void afterCompletion(HttpServletRequest request,                               HttpServletResponse response,                               Object handler, Exception ex) {        TenantContext.clear();    }}

9. 源码分析

9.1 StpLogic 接口设计

Sa-Token 的核心是 StpLogic 接口,它采用了门面模式(Facade Pattern),将复杂的认证逻辑封装在一组简洁的 API 背后。

  +------------------+  |   StpLogic       |  <-- 核心接口  +------------------+       |        |       |        | 实现       v        v  +--------+  +----------+  | StpUtil|  | 自定义   |  | (门面) |  | StpLogic |  +--------+  +----------+       |       | 委托       v  +------------------+  | SaTokenManager   |  +------------------+       |       | 委托       v  +------------------+  | SaSessionDao     |  <-- 数据存储层  +------------------+       |  +----+----+--------+  v         v        v内存     Redis     ZooKeeper

StpLogic 接口的设计体现了接口隔离原则——将所有认证相关操作集中在一个接口中,而不是分散在多个接口中。这样做的好处是:

  1. 1. API 统一:所有认证操作通过一个接口暴露,降低学习成本
  2. 2. 易于扩展:开发者可以实现自己的 StpLogic,替换默认行为
  3. 3. 多账号体系:每个账号类型实例化一个 StpLogic,天然隔离

9.2 Sa-Token 过滤器链

Sa-Token 的过滤器链设计比 Spring Security 简单很多。Spring Security 的过滤器链有十多个过滤器,而 Sa-Token 仅有一个核心拦截器。

  Spring Security Filter Chain:  +-------+-------+-------+-------+-------+-------+-------+  | Channel| Sec. | Logout| Auth. | Basic | Rem.  | Filter|  | Filter | Context|Filter |Entry  | Auth. | Mem.  | Sec.  |  +-------+-------+-------+-------+-------+-------+-------+  Sa-Token Interceptor:  +------------------+  | SaInterceptor    |  | .checkLogin()    |  | .checkPermission |  | .checkRole       |  +------------------+
// SaInterceptor 的核心逻辑@Overridepublic boolean preHandle(HttpServletRequest request,                        HttpServletResponse response,                        Object handler) {    // 如果存在 @SaIgnore 注解,则跳过认证    if (handler instanceof HandlerMethod) {        HandlerMethod handlerMethod = (HandlerMethod) handler;        SaIgnore saIgnore = handlerMethod.getMethodAnnotation(SaIgnore.class);        if (saIgnore != null) {            return true;        }    }    // 执行鉴权逻辑    runAsSuppler(stp);    return true;}

9.3 SSO 认证流程

Sa-Token SSO 的认证流程基于 code 模式,与 OAuth2 的授权码模式类似。

9.4 权限注解扫描机制

Sa-Token 的权限注解(如 @SaCheckPermission)通过 Spring AOP 实现。

// SaAnnotationInterceptor 核心逻辑@Overridepublic Object preHandle(HttpServletRequest request,                       HttpServletResponse response,                       Object handler) {    if (handler instanceof HandlerMethod) {        HandlerMethod handlerMethod = (HandlerMethod) handler;        // 扫描方法上的 SaCheckPermission 注解        SaCheckPermission saCheckPermission =            handlerMethod.getMethodAnnotation(SaCheckPermission.class);        if (saCheckPermission != null) {            // 执行权限校验            StpUtil.checkPermission(saCheckPermission.value());        }        // 扫描方法上的 SaCheckRole 注解        SaCheckRole saCheckRole =            handlerMethod.getMethodAnnotation(SaCheckRole.class);        if (saCheckRole != null) {            StpUtil.checkRole(saCheckRole.value());        }    }    return true;}

注解驱动的设计优势:

方式
优点
缺点
注解式(@SaCheckPermission)
声明式,代码简洁,与业务逻辑分离
需要 AOP 支持
API 式(StpUtil.checkPermission())
灵活,可在任意位置调用
与业务代码耦合
拦截器式(SaInterceptor)
统一配置,全局生效
配置相对复杂

10. 单元测试

10.1 Sa-Token Mock 测试

Sa-Token 提供了专门的测试工具类 SaTokenTestKit,可以在单元测试中模拟登录状态。

@SpringBootTest@AutoConfigureMockMvcclass AuthControllerTest {    @Autowired    private MockMvc mockMvc;    @Test    void testLogin() throws Exception {        // 模拟登录        StpUtil.login(10001L);        // 验证登录态        Assertions.assertTrue(StpUtil.isLogin());        Assertions.assertEquals(10001L, StpUtil.getLoginIdAsLong());        // 获取 Token        String token = StpUtil.getTokenValue();        // 使用 MockMvc 请求受保护接口        mockMvc.perform(get("/user/list")                .header("satoken", token))            .andExpect(status().isOk());    }    @Test    void testLogout() throws Exception {        StpUtil.login(10001L);        Assertions.assertTrue(StpUtil.isLogin());        StpUtil.logout();        Assertions.assertFalse(StpUtil.isLogin());    }}

10.2 权限校验测试

@SpringBootTestclass PermissionTest {    @BeforeEach    void setUp() {        // 清理测试数据        StpUtil.logoutByLoginId(10001L);    }    @Test    void testHasPermission() {        StpUtil.login(10001L);        // 模拟设置权限        List<String> permissions = Arrays.asList("user:add", "user:list", "user:delete");        StpUtil.getSession().set("permission", permissions);        // 验证权限        Assertions.assertTrue(StpUtil.hasPermission("user:add"));        Assertions.assertTrue(StpUtil.hasPermission("user:list"));        Assertions.assertFalse(StpUtil.hasPermission("order:add"));    }    @Test    void testHasRole() {        StpUtil.login(10001L);        // 模拟设置角色        List<String> roles = Arrays.asList("admin", "user");        StpUtil.getSession().set("role", roles);        // 验证角色        Assertions.assertTrue(StpUtil.hasRole("admin"));        Assertions.assertTrue(StpUtil.hasRole("user"));        Assertions.assertFalse(StpUtil.hasRole("super_admin"));    }    @Test    void testCheckPermissionThrows() {        StpUtil.login(10001L);        // 没有设置权限时,校验应抛出异常        Assertions.assertThrows(NotPermissionException.class, () -> {            StpUtil.checkPermission("user:add");        });    }}

10.3 SSO 集成测试

@SpringBootTest@AutoConfigureMockMvcclass SsoIntegrationTest {    @Autowired    private MockMvc mockMvc;    @Test    void testSsoLoginFlow() throws Exception {        // 1. 访问客户端应用,未登录时应重定向        MvcResult result = mockMvc.perform(get("/hello"))            .andReturn();        // 应该被重定向到 SSO-Server        Assertions.assertTrue(            result.getResponse().getRedirectedUrl().contains("sso"));        // 2. 在 SSO-Server 登录        mockMvc.perform(post("/doLogin")                .param("username", "admin")                .param("password", "123456"))            .andExpect(status().isOk());        // 3. 再次访问客户端应用,应已登录        mockMvc.perform(get("/hello"))            .andExpect(status().isOk())            .andExpect(content().string(containsString("admin")));    }}

10.4 Redis 存储测试

@SpringBootTest@TestPropertySource(properties = {    "sa-token.timeout=60",    "spring.data.redis.port=6389"})class RedisStoreTest {    @Autowired    private RedisTemplate<String, Object> redisTemplate;    @Test    void testTokenStoredInRedis() {        // 登录        StpUtil.login(10001L);        String tokenValue = StpUtil.getTokenValue();        // 验证 Redis 中存在对应 Key        String redisKey = "satoken:login:token:" + tokenValue;        Boolean hasKey = redisTemplate.hasKey(redisKey);        Assertions.assertTrue(hasKey);        // 登出后 Key 应被删除        StpUtil.logout();        hasKey = redisTemplate.hasKey(redisKey);        Assertions.assertFalse(hasKey);    }    @Test    void testTokenTimeout() throws InterruptedException {        StpUtil.login(10001L);        // 等待 Token 过期        Thread.sleep(65000);        // Token 应已失效        Assertions.assertFalse(StpUtil.isLogin());    }}

11. 常见误区

误区一:"Sa-Token 不安全"

这是最常见的误解。Sa-Token 的安全性不取决于框架本身,而取决于使用方式。Sa-Token 提供了完整的 Token 管理、权限控制、二级认证等安全机制。关键在于:

  • • Token 传输是否使用 HTTPS
  • • Token 有效期是否合理设置
  • • 敏感操作是否有二次验证
  • • 权限粒度是否适当

Sa-Token 的底层实现遵循了安全最佳实践,其安全性取决于开发者的配置和使用方式。

误区二:"只能做简单认证"

Sa-Token 的功能覆盖范围超出了"简单认证"。从基础登录到 SSO、OAuth2、二级认证、多端独立,Sa-Token 提供了完整的认证授权解决方案。"轻量级"指的是 API 简洁,不是功能有限。

功能
Sa-Token
Spring Security
Shiro
登录认证
Y
Y
Y
权限认证
Y
Y
Y
角色认证
Y
Y
Y
SSO 单点登录
Y
需扩展
需扩展
OAuth2
Y
需扩展
需扩展
二级认证
Y
N
N
多端独立
Y
需扩展
需扩展
同端互斥
Y
需扩展
需扩展
会话管理
Y
Y
Y
记住我
Y
Y
Y
踢人下线
Y
需扩展
需扩展
注解鉴权
Y
Y
Y
路由鉴权
Y
Y
需扩展
临时 Token
Y
N
N

误区三:"不支持分布式"

Sa-Token 通过 sa-token-dao 系列组件支持多种分布式存储方案:

存储方案
依赖
适用场景
内存存储
无需额外依赖
单机部署、开发测试
Redis
sa-token-redis-jackson
生产环境首选
Redisson
sa-token-redisson
需要 Redisson 高级特性
ZooKeeper
sa-token-dao-zookeeper
需要强一致性的场景
Etcd
sa-token-dao-etcd
微服务场景
MySQL
sa-token-dao-redis (自定义 DAO)
需要持久化到数据库的场景

误区四:"与 Spring 深度绑定"

Sa-Token 的核心模块(sa-token-core)不依赖任何 Spring 组件。它与 Spring 的集成通过 sa-token-spring-boot-starter 实现,是可选的。

// 在非 Spring 环境下使用 Sa-Tokenpublic class Main {    public static void main(String[] args) {        // 直接使用 StpUtil,无需 Spring 容器        StpUtil.login(10001L);        System.out.println("isLogin: " + StpUtil.isLogin());        System.out.println("loginId: " + StpUtil.getLoginId());    }}

误区五:"性能不如 Spring Security"

Sa-Token 的 API 调用链更短,过滤器链更简单(只有一个拦截器 vs Spring Security 的十余个过滤器),在大多数场景下性能表现不差。对于大多数业务应用,认证框架的性能差异通常不是瓶颈。

指标
Sa-Token
Spring Security
过滤器数量
1 个拦截器
10+ 个过滤器
登录耗时
~5ms
~8ms
权限校验耗时
~2ms
~4ms
内存占用
低
中

以上数据为参考值,具体性能需根据实际场景进行 JMH 测试。

误区六:"文档不全,遇到问题难解决"

Sa-Token 的官方文档(https://sa-token.cc)提供了完整的中文文档,覆盖入门指南、核心功能、高级特性、常见问题等。此外,社区活跃度较高,GitHub Issues 响应及时。对于国内开发者来说,中文文档的友好度是一个显著优势。

误区七:"没有企业级项目使用"

Sa-Token 已被多个企业和开源项目采用。根据 GitHub 上的 Stars 和 Fork 数据,以及社区反馈,Sa-Token 在国内中小型项目中有较高使用率。选择框架时,应关注其是否满足自身项目的技术需求,而非仅看使用人数。


12. 对比分析

12.1 Sa-Token vs Spring Security

维度
Sa-Token
Spring Security
API 风格
静态方法调用,一行代码
基于 Filter 链,需配置
学习曲线
低(1 天可上手)
高(1-2 周理解核心概念)
核心概念
StpUtil、Token、Permission
Filter、Provider、Manager、Context
配置方式
YAML 配置 + 注解
Java Config + 注解
扩展性
实现 StpLogic 接口
扩展 Filter 或 Provider
生态集成
独立,可选 Spring 集成
Spring 生态深度绑定
安全性
框架提供基础安全机制,依赖开发者配置
提供全面安全机制,默认配置较安全
适合场景
中小型项目、快速开发
大型企业项目、安全要求极高
国际化支持
主要中文
多语言
社区规模
国内活跃
国际活跃

12.2 Sa-Token vs Shiro

维度
Sa-Token
Shiro
维护状态
活跃更新
趋于稳定,更新较少
API 简洁度
极高(一行代码)
中等(需配置 Realm + SecurityManager)
SSO 支持
内置
需自行实现
OAuth2 支持
内置
需自行实现
二级认证
内置
无
多端独立
内置
需自行实现
文档质量
中文文档完善
中文资料较多但部分过时
Spring Boot 集成
官方 Starter
需自行配置
社区活跃度
增长中
稳定

12.3 Sa-Token SSO vs OAuth2 SSO

维度
Sa-Token SSO
OAuth2 SSO
协议标准
自研协议
RFC 标准协议
跨语言支持
仅限 Java
多语言实现
复杂度
简单
中等
第三方集成
不支持
支持(微信、GitHub 等)
适用场景
Java 生态内部系统
需要第三方授权的场景
Token 类型
自研 Token
Access Token + Refresh Token
授权模式
code 模式
authorization_code、client_credentials、password、implicit

13. 最佳实践

13.1 Token 有效期设计

Token 有效期的设计需要在安全性和用户体验之间取得平衡。

场景
建议有效期
说明
管理后台
2-8 小时
工作时间使用,可配合 active-timeout
前台用户
7-30 天
考虑"记住我"场景
移动端
30 天 + 刷新
配合 Refresh Token 机制
敏感操作
30 分钟
二次认证的 Safe Token
临时 Token
10-30 分钟
一次性或短期使用的场景
sa-token:  # Token 有效期 8 小时  timeout: 28800  # 活跃频率 30 分钟:超过 30 分钟未操作则 Token 冻结  active-timeout: 1800

13.2 权限粒度设计

权限粒度设计建议遵循"最小权限原则",同时考虑管理成本。

  权限设计层次:  Level 1: 模块级(user、order、product)    |    +-- Level 2: 操作级(user:add、user:edit、user:delete、user:view)    |    +-- Level 3: 数据级(仅看自己创建的数据 vs 看全部数据)

推荐的权限命名规范:

  格式:{模块}:{操作}  示例:  - user:add        新增用户  - user:edit       编辑用户  - user:delete     删除用户  - user:view       查看用户  - user:export     导出用户  - order:pay       支付订单  - order:refund    退款订单

不推荐的权限粒度:

不推荐
原因
推荐
super_admin
粒度太大,失去权限控制意义
按模块和操作细分
user:add:user
模块重复
user:add
新增用户信息
中文命名不利于国际化
user:add

13.3 Redis 集成配置

生产环境推荐的 Redis 配置:

spring:  data:    redis:      host: ${REDIS_HOST:localhost}      port: ${REDIS_PORT:6389}      password: ${REDIS_PASSWORD:}      database: 0      timeout: 3000ms      lettuce:        pool:          max-active: 16          max-idle: 8          min-idle: 2          max-wait: 1000mssa-token:  timeout: 28800  active-timeout: 1800  is-concurrent: true  is-share: false  token-style: uuid  is-log: false  # 生产环境关闭日志以避免泄露 Token

13.4 安全加固建议

传输安全:

  • • 所有请求使用 HTTPS 传输
  • • Token 不在 URL 中传递(通过 Header 传递)
sa-token:  is-read-cookie: false  is-read-header: true

Token 管理:

  • • 设置合理的 Token 有效期和活跃频率
  • • 敏感操作使用二级认证
  • • 定期清理过期 Token
// 定期清理过期 Token(可配合定时任务)@Scheduled(cron = "0 0 2 * * ?")public void cleanExpiredTokens() {    // Sa-Token 会自动清理过期数据,无需手动处理    // 如需自定义清理逻辑,可通过 SaTokenDao 接口操作}

权限管理:

  • • 遵循最小权限原则
  • • 定期审计权限分配
  • • 权限变更及时刷新 Session

防攻击:

  • • 登录接口增加验证码机制
  • • 限制登录失败次数
  • • 异常登录行为监控
@PostMapping("/login")public Result<String> login(@RequestParam String username,                            @RequestParam String password,                            @RequestParam(required = false) String captcha) {    // 1. 验证码校验    if (!captchaService.verify(captcha)) {        return Result.error("验证码错误");    }    // 2. 登录失败次数限制    String failKey = "login:fail:" + username;    long failCount = SaTokenDao.defaultDao.getTimeout(failKey);    if (failCount > 5) {        return Result.error("登录失败次数过多,请稍后再试");    }    // 3. 验证用户    SysUser user = userService.findByUsername(username);    if (user == null || !passwordEncoder.matches(password, user.getPassword())) {        // 记录失败次数        SaTokenDao.defaultDao.set(failKey, "1", 1800); // 30 分钟内累计        return Result.error("用户名或密码错误");    }    // 4. 登录成功,清除失败记录    SaTokenDao.defaultDao.delete(failKey);    StpUtil.login(user.getId());    return Result.success(StpUtil.getTokenValue());}

14. 总结

14.1 核心要点速查表

要点
说明
一句话定位
轻量级 Java 认证框架,API 简洁,功能丰富
核心 APIStpUtil.login()
、StpUtil.checkLogin()、StpUtil.checkPermission()
核心接口StpLogic
,所有认证操作的抽象
登录认证
一行代码 StpUtil.login(userId)
权限校验
API 方式 StpUtil.checkPermission() / 注解方式 @SaCheckPermission
角色校验
API 方式 StpUtil.checkRole() / 注解方式 @SaCheckRole
Token 存储
默认内存,生产推荐 Redis
多端支持
多端独立、同端互斥
SSO
内置 SSO-Server 和 SSO-Client
OAuth2
内置 OAuth2 协议实现
二级认证StpUtil.openSafe()
 + @SaCheckSafe
适合场景
中小型项目、快速开发、国内项目
学习成本
1 天可上手基本功能

14.2 核心代码速查

// ---- 基础操作 ----StpUtil.login(userId);                    // 登录StpUtil.logout();                         // 登出StpUtil.isLogin();                        // 是否登录StpUtil.getLoginId();                     // 获取账号IDStpUtil.getTokenValue();                  // 获取Token值// ---- 权限操作 ----StpUtil.checkPermission("user:add");      // 校验权限StpUtil.hasPermission("user:add");        // 是否有权限StpUtil.getPermissionList();              // 获取权限列表// ---- 角色操作 ----StpUtil.checkRole("admin");               // 校验角色StpUtil.hasRole("admin");                 // 是否有角色StpUtil.getRoleList();                    // 获取角色列表// ---- 会话操作 ----StpUtil.getSession().set("key", value);   // 设置会话数据StpUtil.getSession().get("key");          // 获取会话数据// ---- 二级认证 ----StpUtil.openSafe(1800);                   // 打开二级认证StpUtil.closeSafe();                      // 关闭二级认证StpUtil.isSafe();                         // 是否已通过二级认证// ---- 踢人下线 ----StpUtil.logoutByLoginId(userId);          // 踢指定用户下线StpUtil.kickout(device);                  // 踢出指定设备

15. 面试自测

👉 Sa-Token认证框架全解析(面试自测与答案)

#
题目
对应章节
Q1
Sa-Token 的核心接口是什么?它的设计体现了什么模式?
概念定义
Q2
一行代码完成 Sa-Token 登录的 API 是什么?底层发生了什么?
快速入门
Q3
Sa-Token 的三种 Token 风格分别是什么?适用场景有何不同?
高级特性
Q4
Sa-Token 的二级认证(Sub-Login)解决了什么问题?如何使用?
高级特性
Q5
Sa-Token 如何实现多账号体系?与单账号体系有什么区别?
与 Spring Boot 集成
Q6
Sa-Token 如何支持分布式部署?有哪些存储方案可选?
常见误区
Q7
Sa-Token SSO 和 OAuth2 SSO 各有什么优缺点?如何选择?
对比分析
Q8
在前后端分离场景中,Sa-Token 的 Token 如何传递?需要注意什么?
分场景讨论
Q9
Sa-Token 的权限注解(@SaCheckPermission)底层是如何实现的?
源码分析
Q10
生产环境中,Sa-Token 有哪些安全加固建议?
最佳实践

16. 参考资料

  1. 1. Sa-Token 官方文档 — Sa-Token 官方文档,涵盖入门指南、核心功能、高级特性
  2. 2. Sa-Token GitHub 仓库 — 源码与 Issue 跟踪
  3. 3. Sa-Token 与 Spring Security 的对比 — 官方对比说明
  4. 4. Sa-Token SSO 单点登录文档 — SSO 功能详细说明
  5. 5. Sa-Token OAuth2 文档 — OAuth2 协议实现说明
  6. 6. Spring Security 官方文档 — Spring Security 参考文档
  7. 7. Apache Shiro 官方文档 — Shiro 参考文档
  8. 8. RFC 6749 - OAuth 2.0 授权框架 — OAuth2 协议标准
  9. 9. Sa-Token 多账号体系示例 — 官方示例仓库

相关学习资料