跳到内容
Lenso
简体中文
Esc
导航打开⌘J预览
本页内容

身份验证与能力

使用平台身份验证提取器和模块功能,无需导入身份验证内部结构。

模块不导入 auth 模块来验证请求。验证是一个 主机关注点通过中间件、请求上下文和 Axum 提取器传递。 在应用 crate 中启用公开 Host HTTP API:

cargo add lenso --features host

请求流程

HTTP request
  -> platform-http middleware reads Authorization or Cookie
  -> ActorResolver chain resolves ActorContext
  -> RequestContext stores the actor
  -> a user-only handler extracts UserActor

当前的演员变体是:

pub enum ActorContext {
    Anonymous,
    User { user_id: String, scopes: Vec<String> },
    Service { service_id: String, scopes: Vec<String> },
    System,
}

用户路由

在生成的主机路由代码中,使用公共主机 HTTP 帮助程序:

use lenso::host::http::{Json, UserActor};
use serde::Serialize;

#[derive(Serialize)]
struct MeResponse {
    user_id: String,
}

async fn me(user: UserActor) -> Json<MeResponse> {
    Json(MeResponse {
        user_id: user.user_id,
    })
}

UserActor 在处理程序之前拒绝匿名、服务和系统参与者 运行。

能力声明

在Manifest中声明模块功能:

use lenso::{ModuleHttpMethod, ModuleHttpRoute, ModuleManifest};

pub fn manifest() -> ModuleManifest {
    ModuleManifest::builder("support/tickets")
        .capabilities(vec![
            "support.tickets.read".to_owned(),
            "support.tickets.assign".to_owned(),
        ])
        .http_routes(vec![ModuleHttpRoute {
            method: ModuleHttpMethod::Post,
            path: "/v1/support/tickets/{ticket_id}/assign".to_owned(),
            capability: Some("support.tickets.assign".to_owned()),
            display_name: Some("Assign ticket".to_owned()),
            story_title: Some("Ticket assigned".to_owned()),
            operation: None,
        }])
        .build()
}

Lenso Console、Surface Gateway 与 Business API 使用这些声明检查 Manifest, 并强制执行已声明 Operation 的访问权限。

检查范围

对于特定于模块的检查,请从参与者读取范围:

use lenso::host::http::{AppError, ErrorCode, Json, UserActor};

fn require_scope(scopes: &[String], required: &str) -> Result<(), AppError> {
    if scopes.iter().any(|scope| scope == required) {
        return Ok(());
    }

    Err(AppError::new(
        ErrorCode::Forbidden,
        format!("missing capability {required}"),
    ))
}

async fn assign_ticket(user: UserActor) -> Result<Json<serde_json::Value>, AppError> {
    require_scope(&user.scopes, "support.tickets.assign")?;
    Ok(Json(serde_json::json!({ "assigned_by": user.user_id })))
}

在 Business API Route Metadata、Surface Grant 与 Console Surface 中使用相同 Capability 名称,使目标授权、Lint 与运维 UI 保持一致。

Auth 模块边界

auth.users 是身份验证锚点,而不是产品配置表。它拥有:

  • 稳定的演员ID
  • 会话分辨率
  • 禁用用户状态
  • 独立于Provider的验证用户记录

产品配置文件数据属于您的模块:

create table app.profiles (
    id text primary key,
    auth_user_id text not null unique,
    display_name text not null,
    created_at timestamptz not null
);

阅读 UserActor.user_id,然后查找您自己的个人资料行。请勿添加产品 姓名、头像、计划、租户或组织成员身份等字段 auth.users

提供者模块

auth-password 在结构上依赖于 auth:它将密码身份存储在 它自己的模式,然后调用 auth 公共帮助程序来创建用户和会话。

这与请求级身份验证不同。普通模块应该依赖 平台提取器和功能字符串,而不是 auth 内部。

最后更新于 2026年8月13日

这个页面有帮助吗?