5.6 KiB
5.6 KiB
/api/auth/logout 当前会话吊销落地设计
日期:2026-04-21
1. 文档目的
这份文档用于指导 M2 中 实现会话吊销 任务的第一段首版落地,冻结:
POST /api/auth/logout的请求与响应 contract。- 当前设备退出时 refresh session 吊销与
token_version递增的组合语义。 - Rust 首版在进程内鉴权真相中的最小实现边界。
- 与后续
logout-all、sessions/:sessionId/revoke的职责切分。
2. 当前基线
当前 Node /api/auth/logout 已具备以下稳定语义:
- 必须先通过 Bearer JWT 校验。
- 从 cookie 中读取当前 refresh token,并尝试吊销对应 refresh session。
- 无论当前 refresh session 是否已存在,只要用户存在,仍继续执行“退出当前设备”。
- 对当前用户执行
token_version + 1,使当前 access token 全局失效。 - 响应成功时始终清理 refresh cookie。
因此,Node 的“退出当前设备”实际是两层组合动作:
- 设备级:吊销当前 refresh session
- 用户级:递增
token_version,让当前 access token 立即失效
Rust 首版必须保留这个语义。
3. 当前阶段范围
本阶段只落以下内容:
module-auth增加当前 refresh session 吊销能力。module-auth增加用户token_version递增能力。api-server暴露POST /api/auth/logout。- 成功或已失效场景统一清理 refresh cookie。
本阶段明确不包含:
/api/auth/logout-all/api/auth/sessions/api/auth/sessions/:sessionId/revoke- 审计日志与风控日志正式落表
- SpacetimeDB reducer 真正写表
4. contract
4.1 请求
- 方法:
POST - 路径:
/api/auth/logout - 请求体:空
- 鉴权:
- Bearer JWT 必填
- refresh cookie 选填但应尽量提供
4.2 成功响应
{
"ok": true
}
同时响应头必须写回清理后的 refresh cookie。
4.3 失败响应
以下情况返回 401 UNAUTHORIZED:
- Bearer JWT 缺失或非法
- JWT 对应用户不存在
说明:
- 当前 refresh cookie 缺失本身不构成
/logout失败。 - 因为当前设备可能已经没有 refresh cookie,但 access token 仍应允许执行显式退出。
5. 固定语义
5.1 当前设备退出的动作顺序
POST /api/auth/logout 固定按以下顺序执行:
- 从 Bearer JWT 解析当前用户。
- 尝试按当前 refresh cookie 吊销 refresh session。
- 对当前用户执行
token_version + 1。 - 返回
ok: true。 - 始终清理 refresh cookie。
5.2 refresh session 吊销是“尽力而为”
当 refresh cookie 缺失、refresh token 无法命中 session、session 已吊销时:
- 不把这些情况视为
/logout失败。 - 继续执行用户级
token_version递增。
原因:
- 当前设备退出的主目标是让“现在这份 access token”立刻失效。
- refresh session 丢失不应该阻断显式退出。
5.3 token_version 必须递增
当前阶段固定规则:
/logout必须递增user.token_version- 后续 Bearer JWT 校验必须比对当前用户最新
token_version
说明:
- 如果不递增,当前 access token 直到自然过期前仍可继续访问。
- 这与 Node 当前行为不一致,也会让“退出登录”在用户感知上失真。
6. 与其他接口的职责切分
6.1 /api/auth/logout
负责:
- 当前设备退出
- 当前 access token 立即失效
- 当前 refresh session 尽力吊销
6.2 /api/auth/logout-all
后续负责:
- 吊销同一用户全部 refresh session
- 递增一次
token_version
6.3 /api/auth/sessions/:sessionId/revoke
后续负责:
- 只吊销指定远端设备 refresh session
- 不递增
token_version
7. crate 边界
7.1 module-auth
负责:
- 按 refresh token hash 吊销当前 session。
- 递增当前用户
token_version。 - 返回退出后最新用户快照,供后续 access token 校验使用。
7.2 platform-auth
负责:
- refresh token 哈希
- 构造清理 cookie 的
Set-Cookie头
7.3 api-server
负责:
- Bearer JWT 与 refresh cookie 的读取
- 调用
module-auth组合执行当前设备退出 - 始终回写清理 cookie
8. 进程内实现策略
当前阶段 module-auth 继续使用进程内真相,新增以下最小能力:
revoke_session_by_refresh_token_hashincrement_user_token_version
其中:
- session 吊销要写入
revoked_at - 用户版本递增要直接修改内存中用户快照
9. Bearer JWT 校验补强
为了让 /logout 后“旧 access token 立即失效”真正成立,当前阶段需要补一条约束:
- Bearer JWT 校验通过签名后,还必须比对 claims 里的
ver - 若
claims.ver != 当前用户 token_version,返回401
说明:
- 这是当前 Rust 鉴权链路必须补上的一致性校验。
- 否则
logout虽然递增了用户版本,但旧 JWT 仍能继续访问。
10. 测试策略
至少覆盖:
- 登录成功后调用
/api/auth/logout返回ok: true /logout成功后会清理 refresh cookie/logout成功后旧 Bearer token 再访问/api/auth/me返回401- refresh cookie 缺失时,只要 Bearer token 有效,
/logout仍返回ok: true - 用户不存在时
/logout返回401
11. 完成定义
满足以下条件时,本任务视为完成:
- Rust 侧已提供
POST /api/auth/logout - 当前 refresh session 可按 cookie 对应关系被吊销
- 用户
token_version会在退出时递增 - Bearer JWT 已补充版本比对
/logout总会清理 refresh cookie- 文档、任务清单与测试已同步更新