fix: 增强云端 Supabase 认证可靠性,修复验证码失败可观测性

- JWT 验证器新增 apikey 参数,支持云端 JWKS 认证头
- Auth 网关新增上游超时/错误映射为 503 状态码
- Auth 网关新增重定向 URL 校验,阻断开放重定向风险
- 用户依赖传递 anon_key 给 JWT 验证器
- 新增相关单元测试覆盖 JWKS 头、503 映射、重定向校验
- 新增实现计划文档
This commit is contained in:
zl-q
2026-03-10 09:11:27 +08:00
parent 6fe2e7b6c3
commit c9a2c75c35
10 changed files with 384 additions and 75 deletions
@@ -0,0 +1,65 @@
# Supabase JWKS Auth Reliability Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 让后端在云 Supabase 场景下稳定使用 JWKS/RS256 验签,并把 Auth 上游超时错误正确暴露为 503,保障注册/登录/重置密码链路可观测。
**Architecture:** 保留 `PUBLIC_URL -> issuer/jwks` 自动推导,JWT 验签继续强制 RS256,但给 JWKS 拉取添加 `apikey``Authorization` 头。Auth Gateway 新增统一错误映射,将上游 timeout/网关错误归类为服务不可用(503),其余保持既有 401/422 语义。
**Tech Stack:** FastAPI, Pydantic, PyJWT (`PyJWKClient`), Supabase Python SDK, pytest。
---
### Task 1: JWKS Header 支持(测试先行)
**Files:**
- Modify: `backend/tests/unit/core/auth/test_jwt_verifier.py`
- Modify: `backend/src/core/auth/jwt_verifier.py`
- Modify: `backend/src/v1/users/dependencies.py`
**Step 1: Write failing test**
-`JwtVerifier` 新增用例,断言初始化 `PyJWKClient` 时会传入 `apikey``Authorization: Bearer <anon_key>`
**Step 2: Run test to verify it fails**
- Run: `uv run pytest backend/tests/unit/core/auth/test_jwt_verifier.py -v`
**Step 3: Write minimal implementation**
- `JwtVerifier.__init__` 新增 `apikey` 参数并注入 JWKS 请求头。
- `get_jwt_verifier()` 传入 `config.supabase.anon_key`
**Step 4: Run test to verify it passes**
- Run: `uv run pytest backend/tests/unit/core/auth/test_jwt_verifier.py -v`
### Task 2: Auth 上游超时错误映射为 503(测试先行)
**Files:**
- Modify: `backend/tests/unit/v1/auth/test_auth_gateway.py`
- Modify: `backend/src/v1/auth/gateway.py`
**Step 1: Write failing test**
- 新增 `create_verification` 的超时错误测试,期望返回 `HTTPException(status_code=503)`
**Step 2: Run test to verify it fails**
- Run: `uv run pytest backend/tests/unit/v1/auth/test_auth_gateway.py -v`
**Step 3: Write minimal implementation**
- 增加 AuthError 分类函数,识别 timeout/request_timeout/upstream timeout。
- 在注册、登录、刷新、重置相关分支中映射为 503。
**Step 4: Run test to verify it passes**
- Run: `uv run pytest backend/tests/unit/v1/auth/test_auth_gateway.py -v`
### Task 3: 回归验证
**Files:**
- Modify: `backend/tests/unit/test_settings_supabase_env.py` (if needed)
**Step 1: Run targeted suites**
- Run: `uv run pytest backend/tests/unit/core/auth/test_jwt_verifier.py backend/tests/unit/v1/auth/test_auth_gateway.py backend/tests/unit/test_settings_supabase_env.py -v`
**Step 2: Run quality gates**
- Run: `uv run ruff check backend/src backend/tests`
- Run: `uv run basedpyright backend/src`
**Step 3: Document runtime checks**
- 记录 JWT/JWKS 必备环境变量和手工联调命令。