feat(saas): Phase 1 后端能力补强 — API Token 认证、真实 SSE 流式、速率限制
Phase 1.1: API Token 认证中间件 - auth_middleware 新增 zclaw_ 前缀 token 分支 (SHA-256 验证) - 合并 token 自身权限与角色权限,异步更新 last_used_at - 添加 GET /api/v1/auth/me 端点返回当前用户信息 - get_role_permissions 改为 pub(crate) 供中间件调用 Phase 1.2: 真实 SSE 流式中转 - RelayResponse::Sse 改为 axum::body::Body (bytes_stream) - 流式请求超时提升至 300s,转发 SSE headers (Cache-Control, Connection) - 添加 futures 依赖用于 StreamExt Phase 1.3: 滑动窗口速率限制中间件 - 按 account_id 做 per-minute 限流 (默认 60 rpm + 10 burst) - 超限返回 429 + Retry-After header - RateLimitConfig 支持配置化,DashMap 存储时间戳 21 tests passed, zero warnings.
This commit is contained in:
@@ -136,7 +136,29 @@ pub async fn refresh(
|
||||
Ok(Json(serde_json::json!({ "token": token })))
|
||||
}
|
||||
|
||||
async fn get_role_permissions(db: &sqlx::SqlitePool, role: &str) -> SaasResult<Vec<String>> {
|
||||
/// GET /api/v1/auth/me — 返回当前认证用户的公开信息
|
||||
pub async fn me(
|
||||
State(state): State<AppState>,
|
||||
axum::extract::Extension(ctx): axum::extract::Extension<AuthContext>,
|
||||
) -> SaasResult<Json<AccountPublic>> {
|
||||
let row: Option<(String, String, String, String, String, String, bool, String)> =
|
||||
sqlx::query_as(
|
||||
"SELECT id, username, email, display_name, role, status, totp_enabled, created_at
|
||||
FROM accounts WHERE id = ?1"
|
||||
)
|
||||
.bind(&ctx.account_id)
|
||||
.fetch_optional(&state.db)
|
||||
.await?;
|
||||
|
||||
let (id, username, email, display_name, role, status, totp_enabled, created_at) =
|
||||
row.ok_or_else(|| SaasError::NotFound("账号不存在".into()))?;
|
||||
|
||||
Ok(Json(AccountPublic {
|
||||
id, username, email, display_name, role, status, totp_enabled, created_at,
|
||||
}))
|
||||
}
|
||||
|
||||
pub(crate) async fn get_role_permissions(db: &sqlx::SqlitePool, role: &str) -> SaasResult<Vec<String>> {
|
||||
let row: Option<(String,)> = sqlx::query_as(
|
||||
"SELECT permissions FROM roles WHERE id = ?1"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user