Files
nuzlocke-tracker/.beans/archive/nuzlocke-tracker-b311--backend-auth-middleware-and-jwt-verification.md
Julian Tabel a6cb309b8b
All checks were successful
CI / backend-tests (push) Successful in 28s
CI / frontend-tests (push) Successful in 28s
chore: archive 42 completed/scrapped beans
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:31:23 +01:00

48 lines
2.2 KiB
Markdown

---
# nuzlocke-tracker-b311
title: Backend auth middleware and JWT verification
status: completed
type: task
priority: normal
created_at: 2026-03-20T15:28:13Z
updated_at: 2026-03-20T20:11:23Z
parent: nuzlocke-tracker-d98o
blocked_by:
- nuzlocke-tracker-2561
---
Add Supabase JWT verification to the FastAPI backend. Create a reusable dependency that extracts and validates the Bearer token, resolves the current user, and provides it to endpoints. Protect all write endpoints (POST/PUT/DELETE) while leaving read endpoints open.
## Checklist
- [x] Add python-jose[cryptography] or PyJWT dependency
- [x] Create auth dependency that extracts Bearer token from Authorization header
- [x] Verify JWT against Supabase JWT secret
- [x] Create `get_current_user` dependency (returns User or None)
- [x] Create `require_auth` dependency (raises 401 if not authenticated)
- [x] Apply `require_auth` to all write endpoints (POST, PUT, DELETE)
- [x] Add tests for auth middleware (valid token, expired token, missing token)
## Summary of Changes
Added JWT authentication middleware to the FastAPI backend:
- Added `PyJWT==2.10.1` dependency to `pyproject.toml`
- Added Supabase config fields (`supabase_url`, `supabase_anon_key`, `supabase_jwt_secret`) to `core/config.py`
- Created `core/auth.py` with:
- `AuthUser` dataclass for authenticated user info
- `_extract_token()` to parse Bearer tokens from Authorization header
- `_verify_jwt()` to validate tokens against Supabase JWT secret (HS256 with "authenticated" audience)
- `get_current_user()` dependency that returns `AuthUser | None`
- `require_auth()` dependency that raises 401 if not authenticated
- Applied `require_auth` to all write endpoints (POST, PUT, PATCH, DELETE) in:
- `runs.py` (3 endpoints)
- `encounters.py` (4 endpoints)
- `genlockes.py` (7 endpoints)
- `bosses.py` (9 endpoints)
- `journal_entries.py` (3 endpoints)
- `games.py` (9 endpoints)
- Added `tests/test_auth.py` with tests for valid/expired/invalid/missing tokens
- Updated `tests/conftest.py` with `auth_client` fixture for tests requiring authentication
- Updated `test_games.py` and `test_runs.py` to use `auth_client` for write operations