# `/api/auth/logout-all` 全端登出落地设计 日期:`2026-04-21` ## 1. 文档目的 这份文档用于指导 `M2` 中 `实现全端登出` 的首版落地,冻结: 1. `POST /api/auth/logout-all` 的请求与响应 contract 2. 全部 refresh session 吊销与 `token_version` 递增的组合语义 3. Rust 首版在进程内鉴权真相中的最小实现边界 4. 与 `/logout`、`/sessions/:sessionId/revoke` 的职责切分 ## 2. 当前基线 当前 Node `/api/auth/logout-all` 已具备以下稳定语义: 1. 必须先通过 Bearer JWT 校验 2. 对当前用户执行 `token_version + 1` 3. 吊销该用户全部未吊销 refresh session 4. 响应成功时始终清理 refresh cookie 因此,Node 的“退出全部设备”同样是两层组合动作: 1. 会话级:吊销同一账号全部 refresh session 2. 用户级:递增 `token_version`,让全部旧 access token 立即失效 Rust 首版必须保留这个语义。 ## 3. 当前阶段范围 本阶段只落以下内容: 1. `module-auth` 增加按 `user_id` 吊销全部 refresh session 的能力 2. `api-server` 暴露 `POST /api/auth/logout-all` 3. 成功场景统一清理 refresh cookie 本阶段明确不包含: 1. `/api/auth/sessions/:sessionId/revoke` 2. 审计日志正式落表 3. SpacetimeDB reducer 真正写表 ## 4. contract ### 4.1 请求 1. 方法:`POST` 2. 路径:`/api/auth/logout-all` 3. 请求体:空 4. 鉴权: - Bearer JWT 必填 - refresh cookie 选填 ### 4.2 成功响应 ```json { "ok": true } ``` 同时响应头必须写回清理后的 refresh cookie。 ### 4.3 失败响应 以下情况返回 `401 UNAUTHORIZED`: 1. Bearer JWT 缺失或非法 2. JWT 对应用户不存在 ## 5. 固定语义 ### 5.1 动作顺序 `POST /api/auth/logout-all` 固定按以下顺序执行: 1. 从 Bearer JWT 解析当前用户 2. 批量吊销当前用户全部 refresh session 3. 对当前用户执行 `token_version + 1` 4. 返回 `ok: true` 5. 始终清理 refresh cookie ### 5.2 `token_version` 只递增一次 无论当前用户存在多少会话: 1. `logout-all` 只递增一次 `token_version` 2. 不为每条 session 单独递增版本号 ### 5.3 缺少 refresh cookie 不影响成功 `logout-all` 是账号级动作,不依赖当前 refresh cookie 命中: 1. 即使当前设备没有 refresh cookie,也要允许完成全端登出 2. 成功响应仍然统一清理 cookie ## 6. 与其他接口的职责切分 ### 6.1 `/api/auth/logout` 负责: 1. 当前设备退出 2. 当前 refresh session 尽力吊销 3. `token_version` 递增一次 ### 6.2 `/api/auth/logout-all` 负责: 1. 全部设备退出 2. 当前用户全部 refresh session 吊销 3. `token_version` 递增一次 ### 6.3 `/api/auth/sessions/:sessionId/revoke` 后续负责: 1. 只吊销指定远端设备 refresh session 2. 不递增 `token_version` ## 7. crate 边界 ### 7.1 `module-auth` 负责: 1. 按 `user_id` 吊销全部 refresh session 2. 递增当前用户 `token_version` 3. 返回最新用户快照 ### 7.2 `platform-auth` 负责: 1. 构造清理 cookie 的 `Set-Cookie` 头 ### 7.3 `api-server` 负责: 1. Bearer JWT 读取与校验 2. 调用 `module-auth` 执行全端登出 3. 始终回写清理 cookie ## 8. 进程内实现策略 当前阶段 `module-auth` 继续使用进程内真相,新增以下最小能力: 1. `revoke_all_sessions_by_user_id` 2. `logout_all_sessions` 其中: 1. 批量吊销只改 `revoked_at` 2. 用户版本递增继续直接修改内存用户快照 ## 9. 测试策略 至少覆盖: 1. 登录两次后调用 `/api/auth/logout-all` 返回 `ok: true` 2. `/logout-all` 成功后清理 refresh cookie 3. `/logout-all` 成功后旧 Bearer token 访问 `/api/auth/me` 返回 `401` 4. `/logout-all` 成功后旧 refresh cookie 调用 `/api/auth/refresh` 返回 `401` 5. 缺少 refresh cookie 时,只要 Bearer token 有效,`/logout-all` 仍返回 `ok: true` ## 10. 完成定义 满足以下条件时,本任务视为完成: 1. Rust 侧已提供 `POST /api/auth/logout-all` 2. 同一用户全部 refresh session 可被吊销 3. 用户 `token_version` 会在全端登出时递增 4. `/logout-all` 总会清理 refresh cookie 5. 文档、任务清单与测试已同步更新