Sa-Token-Rust v0.2.0 发布,被提名 G-Star 孵化项目!

从「能用」到「能放心用」——这是 0.2.0 真正想交付的东西。

我们被看见了,也把自己做硬了

如果你在找 Rust 生态里的认证与授权方案,很可能已经刷到过 sa-token-rust

它是一套轻量、高性能的 Rust 认证授权框架,设计理念对齐 Java 生态中广为人知的 Dromara sa-token,但代码与实现完全独立(MIT OR Apache-2.0)。

最近三件对社区很重要的事:

  1. 项目被「旋武社区」收录
    开放原子开源基金会旗下旋武社区项目页:
    https://xuanwu.openatom.org/articles/project/sa-token-rust/

sa-token-rust 入驻旋武社区开源项目列表

  1. 被提名 AtomGit「G-Star」孵化项目
    G-Star 开源摘星计划 是 AtomGit 面向优质开源项目的全流程扶持(流量、品牌、运营)。入选孵化,仓库会进入官方 G-Star 展台。
    项目详情页:https://atomgit.com/sa-tokens/sa-token-rust

sa-token-rust 入选 AtomGit G-Star

  1. 正式文档站上线(中英双语)
    https://sa-tokens.github.io/sa-token-rust/
    从快速入门、迁移指南,到 StpUtil、存储、OAuth2、SSO、安全能力,一站查齐。

sa-token-rust 入选 AtomGit G-Star

旋武收录、G-Star 提名,是「被看见」;而 0.2.0 这一版,我们真正想说的是:看见之后,能不能经得起生产环境拷问。

过去一段时间,仓库按 A0→F 一整套重构路线,把 0.1.x 时代「功能堆得很多、边界却偏软」的地方,系统性地改到了更接近生产级框架的形态。本文用「以前 vs 现在」的方式,把变化讲清楚。


一句话定位(0.2 仍然成立,但更硬)

sa-token-rust:登录 / 鉴权 / Session / 权限角色 / 多账号多端 / 事件总线 / JWT / OAuth2 / SSO / WebSocket 鉴权 / 在线用户 / 分布式 Session —— 用同一套 StpUtil + SaTokenState 心智模型,覆盖 Axum、Actix-web、Poem、Rocket、Warp、Salvo、Tide、Gotham、Ntex,以及 Tonic gRPC。

0.1.x 已经把「能力清单」铺得很全;
0.2.0 做的是:把能力清单背后的契约、安全默认值、插件一致性、可迁移文档,一次性做对。


为什么要动大手术:0.1.x 的真实痛点

如果只用一句话概括 0.1.x 的问题:

功能多,但「写存储」「读 Token」「踢人清理」「插件鉴权」「初始化失败」等关键路径,各自为政,容易在生产里踩坑。

更具体一点:

痛点 0.1.x 常见表现 生产风险
存储契约弱 序列化散落 serde_json;键名不统一;缺 CAS / scan 等原子能力 多实例不一致、滚动升级困难
Manager 过重 登录、踢人、权限、在线……挤在「上帝对象」里 难测、难改、静默失效
登录非事务 写了一半失败,索引/Token 可能残留 幽灵登录、踢不干净
插件重复 多个 *-core 各写一套中间件 框架间行为不一致
门面易 panic init_manager / 未初始化路径偏硬 库代码里崩进程
安全默认偏松 OAuth2 密钥明文倾向、SSO 验票偏弱、续期默认偏激进 被扫漏洞时很难解释
文档与代码漂移 迁移说明和真实 API 打架 升级成本高、社区信任下降

0.2.0 不是「再加几个 feature」,而是按 A0 工程化 → A 存储 → B 核心 → C 插件/门面 → D 安全 → E 能力对齐 → F 收口与性能 的顺序,把地基换了一遍。


总览:重构路线图

A0  工程化基线(fmt/clippy/版本/门禁/根 facade)
A1  存储原语升级(scan / CAS / list / get_del …)
A2  可插拔序列化(SaSerializer,默认 JSON,可选 fory)
A3  存储键统一(SaKeys / 账号命名空间)
B1  Manager 拆分 + 登录事务化(Dao / Repo / AuthService)
B2  授权体系收敛(AuthzService / 权限匹配)
B3  请求上下文单轨化(SaTokenContext)
B4  事件系统重构(DispatchMode / 超时)
C1  插件收敛到 plugin-common(删除 *-core)
C2  StpUtil 门面重整(try_* / SaLogic 无注册表)
C3  宏层增强
D1  OAuth2 / SSO 安全加固
D2  分布式化与遗留清理
D3  测试补全与文档迁移
E1  与 Java 能力对齐补齐(Sign / TempToken / Same-Token …)
E2  配置项落地与 Token 读写链路(token_io)
F   收口与性能(Arc 化、分片缓存、旁路清理)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

下面按大家最关心的点展开对比。


对比一:工程化 —— 从「能编译」到「能发布」

以前(0.1.x)

  • 版本号分散,示例与门禁偶发红灯
  • 发布链路对质量门禁依赖弱
  • 根包「一键引入」体验不完整

现在(0.2.0)

  • Workspace 版本统一 0.2.0,内部依赖进 [workspace.dependencies]
  • 发布脚本 scripts/publish_all.sh 内置质量门禁:
    cargo fmt --checkclippy -D warningscargo test --workspace
  • 根 crate sa-token-rust 作为 facade,方便 cargo add
  • MSRV、docs.rs、resolver 等元数据补齐

对你意味着什么:
开源项目不只是「仓库里有代码」,而是 可持续发布、可复现构建。旋武社区收录的是一个能交付的工程,而不只是一个 README。


对比二:存储层 —— 从「随便 to_string」到「契约 + 可升级」

以前

  • 存储读写路径大量硬编码 JSON
  • 键名散落各处,多账号隔离靠约定而非统一布局
  • 原子能力(CAS、scan、list)不齐或后端不一致

现在

能力 说明
SaTokenDao 唯一存储漏斗:键 + 序列化 + TTL
SaKeys 统一键布局与账号命名空间(login_type 隔离)
SaSerializer 可插拔编码;默认 JSON;可选 fory 二进制 + 滚动升级读存量 JSON
SaStorage 原语 scan / get_del / compare_and_swap / list_* 等生产向能力

Memory / Redis / Database(PostgreSQL KV)仍可按插件 feature 切换;业务侧应走 Dao,而不是在服务里直接握底层存储。

对你意味着什么:
换 Redis、扩多实例、以后换编码格式,路径是清晰的;不再「每个模块自己发明一种存法」。

文档入口:Storage 指南


对比三:核心架构 —— 从「上帝 Manager」到「分层 + 事务登录」

以前

  • SaTokenManager 职责过重
  • 登录写入非阶段化,失败易残留
  • 踢人 / 顶号 / 最大登录数等边界有已知缺陷风险
  • Token 读路径自动续期默认偏激进,可能「每次读都写存储」

现在

请求 / StpUtil
    ↓
SaTokenManager(薄门面)
    ↓
AuthService / AuthzService
    ↓
TokenRepo / SessionRepo / GrantRepo
    ↓
SaTokenDao → SaStorage
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

关键变化:

  1. 登录事务化:阶段写入 + 失败逆序补偿,login:token 用 CAS 作为提交点
  2. 踢人 / 登出模式:清理路径统一,减少幽灵 Token
  3. auto_renew 默认改为 false:避免每次鉴权都打存储;需要旧行为时显式打开,并可配 renew_threshold
  4. 权限 / 角色AuthzService,与登录事务边界清晰

对你意味着什么:
「登录成功」更接近真正的业务事务语义;「踢人失败却还在线」这类诡异问题显著减少。


对比四:插件与框架 —— 从「五套 core」到「一套 common」

以前

  • 多个 sa-token-plugin-*-core 重复实现状态、拒绝体、扩展写入
  • Warp 等个别框架曾绕过统一鉴权流,行为不一致
  • Extractor 缺 Token 时的 HTTP 状态码不统一

现在

  • 新建 sa-token-plugin-commonSaTokenState / rejection / snapshot / ext 一处维护
  • 删除*-core crate
  • 全框架对齐 run_auth_flow:读 Token、写上下文、路径鉴权同一条链路
  • Actix / Rocket / Salvo / Gotham / Ntex 仍是 门面 + 版本绑定 feature;Axum / Poem / Warp / Tide / Tonic 一体化插件

对你意味着什么:
换框架时,心智模型不变:还是 SaTokenState + 中间件 / Layer + StpUtil。少学一套「这个框架特供的坑」。

文档入口:Framework integration


对比五:StpUtil 门面 —— 从「能 panic」到「Result 优先」

以前

  • init_manager 作为主路径,失败易直接崩
  • 多账号依赖全局注册表(put_stp_logic
  • 默认路径 login_type 分裂:权限已跟上下文,踢人/Session 仍可能写死 default
  • TokenBuilder / Token-Session / 按类型封禁等能力不齐

现在

API / 概念 0.2 行为
try_init_manager / try_get_manager 返回 Result;重复初始化 → AlreadyInitialized
init_manager 废弃(仍可能 panic,不推荐)
SaLogic 廉价 Clone 门面,无进程级注册表;put_stp_logic 为废弃空操作
login / login_with_extra 固定 default 账号体系(不偷偷跟上下文)
kick_out / disable / Session 等短方法 跟当前请求 login_type,否则 default
TokenBuilder 支持 nonce / expire_at / expire_at_unix
Token-Session / kick_out_by_token / disable_with_type 门面补齐

对你意味着什么:
库代码可以优雅处理「未初始化 / 已初始化」;多账号写法变成「拿一个 SaLogic 钉死类型」,而不是维护一张全局表。

文档入口:StpUtil · 多账号


对比六:请求上下文与宏 —— 单轨、可预测

以前

  • 上下文与宏、中间件之间存在双轨风险
  • #[sa_ignore] 容易被误解成「中间件也放行」

现在

  • SaTokenContext 单轨化:请求级上下文清晰,宏与中间件共用同一套元数据思路
  • PathAuthConfig::exclude:公开路由必须写进排除列表
  • #[sa_ignore]:只跳过宏插入的检查,绝不绕过 Layer / Middleware
  • #[sa_check_login]:走异步强校验(存储仍有效),handler 需 async

这是很多线上事故的「根因级」修正:公开路由靠配置声明,而不是靠宏碰运气。

文档入口:路径鉴权


对比七:安全默认值 —— OAuth2 / SSO / Token 读写

OAuth2 / SSO(以前 vs 现在)

以前倾向 0.2.0
Client Secret 易明文落库 Argon2id PHC 哈希存储与校验
公共客户端 PKCE 弱或缺失 强制 PKCE(S256)
Refresh 轮换与失败回写不严 原子 take + 失败回写
OAuth2/SSO 存储 进程内 HashMap Dao 持久化
SSO 验票 偏弱 真消费票据 + HMAC 请求签名
统一登出 能力有限 SloNotifier(HTTP 实现按 feature)

Token 读写链路

统一走核心 token_io

  • read_token:按 is_read_header / is_read_cookie / is_read_body 真实生效
  • token_prefix:可选前缀(如 Bearer
  • is_write_cookie + write_token_cookie:登录写 Cookie 默认关闭、需显式打开

其它安全能力补齐

  • 通用 请求签名 RequestSign
  • 临时令牌 TempToken
  • Same-Token 加固(CSPRNG + CAS 刷新)
  • 登录 Token 唯一性重试max_try_times

对你意味着什么:
默认值更保守、更可审计;需要旧行为时必须「知情同意」地打开开关。

文档入口:Security · OAuth2 · SSO


对比八:事件、性能与收口

事件总线

  • DispatchMode:Sequential / Concurrent / Detached
  • Listener 超时可控;未初始化时 event_bus() 返回 None,不再硬崩

性能与收口

  • Config / TokenValue 等关键路径 Arc 化,降低 Clone 成本
  • MemoryStorage 分片;GrantCache 分片 + flight 锁
  • 清理 Dao 旁路;Refresh 索引走统一 Repo
  • 插件读 Token 统一 token_io

这些改动不喧哗,但决定了高并发下「稳不稳、抖不抖」。


对比九:文档与社区交付 —— 从「仓库说明书」到「双语站点」

以前

  • 文档分散、中英不对等、与代码偶有矛盾(例如迁移文写「没有 token_prefix」)
  • 旋武收录页目前仍主要镜像较早的 README 能力清单(功能全,但尚未体现 0.2 架构叙事)

现在

从 0.1.x 升级的同学,先读迁移指南再改依赖;新同学直接从 快速入门 开始。


一张表:0.1.x → 0.2.0 速查

维度 0.1.x 0.2.0
版本 分散(如 0.1.18) 统一 0.2.0
初始化 init_manager 主路径 try_init_manager / try_build
存储访问 服务常直连 SaStorage SaTokenDao 收口
序列化 硬编码 JSON SaSerializer 可插拔
键布局 分散 SaKeys + 账号命名空间
登录 非事务、易残留 阶段写入 + 补偿
续期 默认偏激进 auto_renew 默认 false
插件状态 多个 *-core sa-token-plugin-common
多账号 全局注册表 SaLogic 廉价 Clone,无注册表
公开路由 易误解 sa_ignore PathAuthConfig::exclude
OAuth2 密钥 偏明文 Argon2id + PKCE
SSO 进程内 / 验票弱 Dao + 真验票 + 签名
Token 读写 各插件略异 统一 token_io
文档 分散、易过时 双语 VitePress + MIGRATION

最小代码体感(0.2 推荐写法)

use sa_token_plugin_axum::*;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let state = SaTokenState::builder()
        .storage(Arc::new(MemoryStorage::new()))
        .timeout(7200)
        .build(); // 内部 try_init_manager

    // 库代码更推荐:
    // let mgr = SaTokenConfig::builder()
    //     .storage(Arc::new(MemoryStorage::new()))
    //     .try_build()?;

    let token = StpUtil::login("10001").await?;
    println!("token = {token}");

    // 多账号:钉死 login_type
    let admin = StpUtil::stp_logic("admin")?;
    let admin_token = admin.login("10001").await?;

    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

公开路由请记得:

PathAuthConfig::new()
    .exclude("/api/login")
    .exclude("/health");
  • 1
  • 2
  • 3

而不是指望单独一个 #[sa_ignore] 就能放行中间件。


你可以怎么开始

1. 新项目选型

直接上 0.2.0。从文档站 Quick start 进,按框架选插件 crate,Memory 开发、Redis 生产。

2. 0.1.x 存量项目

迁移指南 清单改:

  • 依赖升到 0.2.0
  • *-coreplugin-common / 插件 prelude
  • init_managertry_init_manager
  • 公开路由 → PathAuthConfig::exclude
  • 按需打开 auto_renew / token_prefix / is_write_cookie
  • OAuth2 / SSO 按新安全模型重读一遍

3. 关注开源与社区的朋友

旋武收录、G-Star 提名,证明项目进入了更广的开源视野;
0.2 的意义是:在被看见之后,把工程质量配得上这份看见。


我们真正想交付的,不只是「又一个 Auth 库」

认证授权框架的价值,从来不在「功能列表有多长」,而在于:

  • 失败时会不会把半截状态写进 Redis;
  • 换一个 Web 框架,行为会不会悄悄变;
  • 默认配置会不会在你不知情时「每次读 Token 都写库」;
  • 文档写的 API,能不能和 crates.io 上的二进制对得上。

sa-token-rust 0.2.0 做的,就是把这些问题从「靠经验躲开」变成「靠架构默认正确」。

欢迎 Star、提 Issue、提 PR;
也欢迎把文档站收藏进团队内部 Wiki——下次选型时,少踩一轮坑。

相关链接

说明 链接
正式文档(中英) https://sa-tokens.github.io/sa-token-rust/
旋武社区收录页 https://xuanwu.openatom.org/articles/project/sa-token-rust/
AtomGit / G-Star 详情页 https://atomgit.com/sa-tokens/sa-token-rust
GitHub 仓库 https://github.com/sa-tokens/sa-token-rust
Gitee 仓库 https://gitee.com/sa-tokens/sa-token-rust
Issues https://github.com/sa-tokens/sa-token-rust/issues
0.2 迁移说明 MIGRATION_0.2.md
crates.io(搜索 sa-token) 统一版本 0.2.0

设计灵感来自 Dromara sa-token;本仓库为 独立 Rust 实现,许可证 MIT OR Apache-2.0,详见仓库 NOTICE

← Sa-Token v1.46.0 发布 🚀,新增 Apache Fory 集成、独立 Redisson 集成

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

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