fix(auth): tighten refresh session revocation
This commit is contained in:
@@ -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` 字段 | 迁移规则 |
|
||||
|
||||
Reference in New Issue
Block a user