Files
social-app/docs/plans/2026-03-10-auth-token-compat-refresh-singleflight.md
T

70 lines
3.0 KiB
Markdown
Raw Normal View History

# Auth Token Compatibility + Refresh Singleflight Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 兼容云 Supabase 实际 access token claims(缺失 `iss` 仍可通过),并修复前端 401 导致 refresh 风暴问题,消除日志中的批量 401/429 警告。
**Architecture:** 后端保持 HS256 签名校验、`exp/sub` 必检,将 `iss` 从“强制存在”改为“存在时校验”;前端在拦截器中加入 refresh 单飞与防重入,避免并发 401 触发多次 refresh 或 refresh 自递归。同步清理无效分支与冗余状态。
**Tech Stack:** FastAPI, PyJWT, Flutter, Dio, flutter_test
---
### Task 1: 后端 JWT claim 兼容化(无 `iss` 可通过)
**Files:**
- Modify: `backend/src/core/auth/jwt_verifier.py`
- Test: `backend/tests/unit/core/auth/test_jwt_verifier.py`
**Step 1: Write failing test**
- 新增用例:token 不含 `iss`、但 `sub/exp` 与 HS256 签名合法时应验证成功。
**Step 2: Run test to verify it fails**
- Run: `cd backend && uv run pytest tests/unit/core/auth/test_jwt_verifier.py -q`
**Step 3: Write minimal implementation**
- `jwt.decode``require` 去掉 `iss`,仅保留 `sub/exp`
- 若 payload 中存在 `iss` 且配置了 issuer,则手动比对 issuer;不一致时报错。
**Step 4: Run test to verify it passes**
- Run: `cd backend && uv run pytest tests/unit/core/auth/test_jwt_verifier.py -q`
### Task 2: 前端 refresh 单飞 + 防递归
**Files:**
- Modify: `apps/lib/core/api/api_interceptor.dart`
- Test: `apps/test/core/api/api_interceptor_test.dart`
**Step 1: Write failing tests**
- 并发 401 时只调用一次 `onTokenRefresh`
- `/api/v1/auth/sessions/refresh` 自身 401 不触发 refresh 重试。
**Step 2: Run tests to verify failures**
- Run: `cd apps && flutter test test/core/api/api_interceptor_test.dart`
**Step 3: Write minimal implementation**
- 增加 `_refreshFuture` 单飞字段。
- 非 refresh 请求命中 401 时 await 同一个 refresh future。
- 对 refresh/logout 认证端点和已重试请求加短路,避免无限重入。
**Step 4: Run tests to verify pass**
- Run: `cd apps && flutter test test/core/api/api_interceptor_test.dart`
### Task 3: 清理无效/旧分支并做回归验证
**Files:**
- Modify: `apps/lib/core/api/api_interceptor.dart`(移除无效重试分支)
- Modify: `backend/src/core/auth/jwt_verifier.py`(删除不再使用的路径)
**Step 1: Refactor cleanup**
- 删除不再可达的分支与重复逻辑,保持行为不变。
**Step 2: Full targeted verification**
- Run: `cd backend && uv run ruff check src tests`
- Run: `cd backend && uv run basedpyright`
- Run: `cd backend && uv run pytest tests/unit/core/auth/test_jwt_verifier.py tests/unit/v1/users -q`
- Run: `cd apps && flutter test test/core/api/api_interceptor_test.dart test/features/auth`
**Step 3: Runtime spot-check**
- Run: 登录拿 token 后请求 `/api/v1/agent/history`,确认不再因缺失 `iss` 返回 401。