# 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。