Files
Genarrative/docs/technical/AUTH_LOGOUT_ALL_DESIGN_2026-04-21.md
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

4.2 KiB
Raw Blame History

/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 成功响应

{
  "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 单独递增版本号

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. 文档、任务清单与测试已同步更新