fix(auth): tighten refresh session revocation

This commit is contained in:
2026-05-13 15:04:37 +08:00
parent b13870f71b
commit 4fecf9c975
36 changed files with 1664 additions and 170 deletions

View File

@@ -115,6 +115,8 @@
1. 从 cookie 读出原始 refresh token
2. 计算 hash
3.`refresh_session.refresh_token_hash` 比较
4. 若 refresh cookie 缺失或不可用,再使用 Bearer access token claims 中的 `sid``refresh_session.session_id` 比较
5. 会话列表按“同设备 + 同 IP”聚合时组内任一 session 命中当前 hash 或当前 `sid`,整组都视为当前设备组
## 5. 表访问级别
@@ -228,9 +230,10 @@
写入规则:
1. 按当前 cookie 找 session
2. `revoked_at = now`
3.`revoked_reason_code = logout`
4. 同时提升 `user_account.token_version`
2. 如果 refresh cookie 缺失,则回退用 Bearer access token claims 中的 `sid` 找当前 session
3.`revoked_at = now`
4. `revoked_reason_code = logout`
5. 同时提升 `user_account.token_version`
### 8.4 吊销全部会话
@@ -248,7 +251,7 @@
触发点:
1. `POST /api/auth/sessions/:sessionId/revoke`
1. `POST /api/auth/sessions/{sessionId}/revoke`
写入规则:
@@ -257,6 +260,13 @@
3. 只改目标 `refresh_session`
4. `revoked_reason_code = session_revoke`
5. 不提升 `token_version`
6. 撤销后必须同步 auth store 到 SpacetimeDB
读取约束:
1. Bearer JWT 中的 `sid` 必须对应 active `refresh_session`
2. 被该接口撤销的设备即使 access token 未过期,后续请求也必须立刻返回未授权
3. 该接口不承担当前设备退出语义;当前设备退出固定走 `/api/auth/logout`
### 8.6 账号被禁用或并入
@@ -315,13 +325,18 @@
1. `clientLabel` 当前阶段继续兼容保留,但固定与 `deviceDisplayName` 对齐。
2. `ipMasked``isCurrent` 继续在 Axum 侧派生。
3. 同设备同 IP 的 active sessions 由 Axum 聚合后返回一条记录。
4. `sessionId` 是代表 ID当前组代表 ID 使用当前 `sid` 对应 session。
5. `sessionIds` 返回组内全部 active session ID`sessionCount` 返回组内数量。
6. 聚合组时间语义:`createdAt` 取最早创建时间,`lastSeenAt``expiresAt` 取最新值。
### 10.3 `POST /api/auth/logout`
依赖:
1. 当前 cookie 命中的 `refresh_session`
2. `user_account.token_version`
2. cookie 缺失时 Bearer `sid` 命中的 `refresh_session`
3. `user_account.token_version`
### 10.4 `POST /api/auth/logout-all`
@@ -330,6 +345,22 @@
1. 当前 `user_id` 下全部活跃 `refresh_session`
2. `user_account.token_version`
### 10.5 `POST /api/auth/sessions/{sessionId}/revoke`
依赖:
1. 当前 Bearer JWT 的 `user_id`
2. 当前 Bearer JWT 的 `sid`
3. 目标 `refresh_session.session_id`
4. `refresh_session.revoked_at`
5. `refresh_session.expires_at`
固定行为:
1. 目标 session 必须属于当前用户
2. 目标 session 不能是当前 `sid`
3. 成功只撤销目标 session不递增 `token_version`
## 11. 与当前 Node `user_sessions` 的映射关系
| Node `user_sessions` 列 | 新 `refresh_session` 字段 | 迁移规则 |