☰
从 Ctx 上下文到访问控制:rust-web-app 请求上下文设计与 ACS 权限系统路线图(完整指南)
2026/9/28 4:41:26 网站建设 项目流程

从 Ctx 上下文到访问控制:rust-web-app 请求上下文设计与 ACS 权限系统路线图(完整指南)

【免费下载链接】rust-web-appCode template for a production Web Application using Axum: The AwesomeApp Blueprint for Professional Web Development.项目地址: https://gitcode.com/gh_mirrors/ru/rust-web-app

rust-web-app 是一个基于Axum框架的生产级 Rust Web 应用模板(AwesomeApp Blueprint),它不仅提供了完整的登录认证与 JSON-RPC 动态路由,还精心设计了Ctx 请求上下文,并为未来的ACS 访问控制(Access Control System)权限系统预留了完整演进路线。本文将带你快速理解这套请求上下文如何贯穿一次 HTTP 请求的完整生命周期,以及 PBAC 权限系统将如何分阶段落地。

一、为什么需要 Ctx 请求上下文?🧭

在很多 Web 框架中,"当前用户是谁"往往散落在 session、header 解析或全局变量里。rust-web-app 的做法更简洁:用一个轻量结构体Ctx承载整个请求的身份上下文,并让它贯穿从 HTTP 中间件到业务模型层的每一层。

核心定义见 ctx/mod.rs:

pub struct Ctx { user_id: i64, /// Note: For the future ACS (Access Control System) conv_id: Option<i64>, }

Ctx只有两个字段,却承担了三重职责:

字段职责说明
user_id身份标识当前请求用户的数据库 ID,为0时表示"根/匿名"上下文
conv_id容器作用域预留字段,为 ACS 按会话(Conv)粒度做权限判定而设计
结构本身上下文传递作为 JSON-RPC 资源注入每个 RPC 方法,业务层无需再解析请求头

Ctx 的三种创建方式

  1. Ctx::root_ctx()—— 系统级/未认证上下文,user_id = 0,用于登录等无需身份的接口(见 handlers_login.rs);
  2. Ctx::new(user_id)—— 正常认证用户上下文,且明确拒绝创建 user_id 为 0 的普通上下文(见 ctx/mod.rs),从类型层面杜绝"伪用户";
  3. ctx.add_conv_id(conv_id)—— 派生一个带会话作用域的上下文,这是未来 ACS 权限判定的关键扩展点(见 ctx/mod.rs)。

二、从 Cookie 到 Ctx:一次请求的完整旅程 🚀

理解了Ctx是什么,再看它如何被"造出来"。整个流程由 main.rs 中定义的中间件链驱动,执行顺序从外到内为:

请求 → mw_req_stamp(请求打点) → CookieManager(Cookie 管理) → mw_ctx_resolver(解析身份,永不失败) → [/api 路由] mw_ctx_require(强制认证) → 业务 Handler

1. mw_ctx_resolver:永不失败的上下文解析器

这是整个认证链最巧妙的设计(见 mw_auth.rs)。它完成四步:

  1. 取 Cookie—— 从请求 Cookie 中读取认证令牌;
  2. 查用户—— 通过令牌中的用户名查询UserForAuth;
  3. 验签—— 校验令牌签名与过期时间;
  4. 构建 Ctx—— 调用Ctx::new(user.id)生成上下文,并将结果(含可能的错误)放入请求扩展(request extensions)中传递。

关键在于它的错误策略:resolver 本身永远不会"失败",而是把潜在错误(如令牌缺失、格式错误、验签失败,见 CtxExtError)包装进结果中继续往下传。这样既不妨碍下游中间件执行,又能让需要强制认证的mw_ctx_require或具体 Handler 按需取出精确的错误信息——这是典型的"解析与裁决分离"设计。

2. mw_ctx_require:API 路由的守门员

/api(JSON-RPC)路由通过route_layer单独挂载了 mw_ctx_require,它取出上一步的解析结果,一旦认证失败立即拒绝请求。而登录路由不挂这层,因此无需身份也能访问——权限边界在路由装配时就被清晰划定。

3. 令牌是如何签发的?

登录成功后,api_login_handler 会校验密码(支持多方案哈希与自动升级),并写入令牌 Cookie。令牌格式为ident.exp.sign三段式 Base64URL 编码(见 token/mod.rs):

段含义
ident用户标识(用户名)
expRFC3339 过期时间
sign用BLAKE3对用户盐值 + 全局密钥计算的签名

验签时服务端用相同算法重算签名比对,并检查过期时间(见 validate_token_sign_and_exp)。由于盐值存在数据库中,重置盐值即可让该用户所有旧令牌失效——这是相当优雅的"服务端注销"机制。

三、Ctx 如何流入 JSON-RPC 业务层 🔁

认证完成后,上下文要真正"流"到业务代码中。JSON-RPC 入口 rpc_axum_handler 做了两件事:

  1. 通过CtxW提取器从请求扩展中取出Ctx(提取器实现见 mw_auth.rs);
  2. 用resources_builder![ctx]将 Ctx 作为请求级资源叠加到基础 RPC 路由上。

于是任何 RPC 方法都能像 add_conv_msg 这样直接声明ctx: Ctx参数,上下文自动注入:

pub async fn add_conv_msg( ctx: Ctx, // ← 由框架自动注入 mm: ModelManager, params: ParamsForCreate<ConvMsgForCreate>, ) -> Result<DataRpcResult<ConvMsg>> { ... }

至此,Ctx完成了Cookie → 中间件 → 请求扩展 → RPC 资源 → 模型层 BMC的全链路传递,业务代码永远不需要手动"找用户"。

四、ACS 权限系统路线图:PBAC 如何落地 🗺️

项目已经为访问控制埋好了种子。model/acs/mod.rs 中标注着 "TO BE IMPLEMENTED",明确了技术路线:基于权限的访问控制(PBAC, Privilege Based Access Control),并与核心容器结构(Org组织、Space空间、Conv会话)绑定。

1. 现有代码中的"路标"

  • ConvScopedtrait:让拥有conv_id的实体可以被 Ctx "升级",携带会话作用域参与权限判定(见 conv.rs);
  • 权限注解草案:ConvBmc::add_msg 的注释中已勾勒出目标 API 形态——
// For access constrol, we will add: // #[ctx_add(conv, space)] // #[requires_privilege_any_of("og:FullAccess", "sp:FullAccess", "conv@owner_id" "conv:AddMsg")]
  • TODO 校验点:ConvBmc::get_msg 中预留了"先查询、再断言conv:ReadMsg权限"的检查位。

2. 权限命名与设计思路

从草案注解可以读出清晰的权限分级:og:(Org 组织级)>sp:(Space 空间级)>conv:(会话级),支持"任一权限满足即放行"(requires_privilege_any_of),并支持conv@owner_id这类基于资源属主的动态权限。这与多租户工作区(类似 GitHub 仓库、Discord 服务器)的常见权限模型一致。

3. 落地路线图

阶段内容状态
✅ 已完成Ctx.conv_id预留字段 +add_conv_id()派生代码已就位
✅ 已完成ConvUser多用户会话成员表(见 conv_user.rs)表结构与 BMC 已建
🔜 规划中PBAC 权限模型:Org / Space / Conv三级权限与assert_privileges断言待实现
🔜 规划中声明式权限宏(#[requires_privilege_any_of]),与现有generate_common_bmc_fns宏风格一致待实现

其中Conv实体已区分 OwnerOnly / MultiUsers 两种会话类型,并携带owner_id——这些正是会话级权限判定的数据基础。

五、新手快速上手清单 ✅

想亲手跑起来看看?三步即可:

  1. 克隆仓库(本地无网络环境可用镜像):
    git clone https://gitcode.com/gh_mirrors/ru/rust-web-app
  2. 启动 PostgreSQL(Docker 一行命令,见 README.md "Starting the DB" 一节),并按 sql/dev_initial/ 下的00-recreate-db.sql、01-create-schema.sql、02-dev-seed.sql初始化数据库;
  3. 运行服务:
    cargo run -p web-server

项目结构速览

目录职责
crates/libs/lib-core/核心模型层:Ctx上下文、acs权限模块、Conv/ConvMsg 等实体
crates/libs/lib-auth/认证能力:多方案密码哈希、令牌生成与验签
crates/libs/lib-web/Web 层:登录 Handler、RPC 动态路由、认证中间件
crates/libs/lib-rpc-core/JSON-RPC 参数/结果的通用类型与宏
crates/services/web-server/服务入口:路由装配、RPC 方法注册
crates/tools/gen-key/开发辅助:生成令牌密钥

建议的阅读顺序

  1. 从 ctx/mod.rs 入手,理解上下文本体(仅 50 余行);
  2. 顺着 mw_auth.rs 走一遍 Cookie → Ctx 的解析链;
  3. 最后查看 conv.rs 中的权限注释,把握 ACS 的演进方向。

总结 📌

rust-web-app 用一个仅含两个字段的Ctx结构体,就把"身份"这件事从登录、认证中间件到 JSON-RPC 业务层串成了一条清晰可控的链路;而conv_id预留字段、ConvScopedtrait 与 PBAC 权限注解草案,则为下一步的Org → Space → Conv 三级访问控制系统铺好了地基。如果你正在用 Rust 构建生产级 Web 应用,这套"上下文先行、权限渐进"的设计非常值得借鉴。

【免费下载链接】rust-web-appCode template for a production Web Application using Axum: The AwesomeApp Blueprint for Professional Web Development.项目地址: https://gitcode.com/gh_mirrors/ru/rust-web-app

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询