Architecture
请求管道
每个 API 请求都需要经过的统一身份验证、授权与速率限制关卡。
每个 API 请求在执行任何业务逻辑之前,都会经历相同的审查流程。这些关卡是单一、可复用的实现——而非针对各路由的独立代码——因此安全行为在整个接口层面保持一致。
各关卡说明
中间件 — 检查会话是否存在,应用内容安全策略,并在维护模式下提前中断请求。
身份验证 — 验证 Firebase 会话 Cookie(或服务间调用使用的内部 JWT),并与数据库用户进行对账。失败时返回
401。
授权(RBAC) — 解析调用方对目标实体的最高权限授予(读取 < 写入 < 管理员),权限范围限定在工作区内。失败时返回
403。
速率限制 — 针对高开销路由和公开路由的滑动窗口计数器。失败时返回 429。
处理器 — 经过验证的请求到达经 Zod 校验的业务逻辑。
请求流程
sequenceDiagram
autonumber
actor C as Caller
participant E as Edge
participant G as API Guards
participant A as Auth
participant Z as RBAC
participant L as Rate Limiter
participant H as Handler
C->>E: HTTPS request
E->>G: Route handler
G->>A: requireApiAuth()
A-->>G: session or null
alt not authenticated
G-->>C: 401 Unauthorized
else authenticated
G->>Z: requireWorkspaceAccess(min)
Z-->>G: permission or null
alt insufficient permission
G-->>C: 403 Forbidden
else authorized
G->>L: checkRateLimit(key)
alt limit exceeded
L-->>C: 429 Too Many Requests
else within limit
G->>H: validated request
H-->>C: 200 + data
end
end
end速率限制存储
限流器默认使用进程本地的内存滑动窗口。当配置了 Redis URL 时,它会切换到由 Memorystore 支持的滑动窗口(原子 Lua 脚本),并在所有服务器实例间共享,从而防止单个用户通过将请求分散到多个副本来绕过限制。
Redis 客户端采用懒加载连接方式,限流器在失败时回退到内存模式——缓存故障永远不会导致启动崩溃或请求返回 500。在 Redis 恢复之前,系统将降级为按实例的速率限制。
租户隔离
授权始终是工作区范围的。一条授权记录以 (userId, entityType, entityId) 为键,执行器会将 userId 和 workspaceId 贯穿整个运行过程——因此工作流只能在其所属租户边界内读写数据。请参阅多租户。