Files
CA/backend/auth/CLAUDE.md

43 lines
1.4 KiB
Markdown
Raw Normal View History

# Auth — JWT Authentication
## Stack
python-jose (JWT signing/verification) + passlib (bcrypt password hashing). Token-based, stateless.
## Structure
```
auth/
models.py # Pydantic models: UserCreate, UserLogin, Token, UserOut
service.py # Business logic: authenticate_user, create_user, create_access_token
dependencies.py # FastAPI Depends: get_current_user, require_admin
middleware.py # ASGI middleware (if any global auth checks)
router.py # APIRouter: /login, /register, /whoami
```
## Patterns
- Passwords hashed with bcrypt via `passlib` — never store plaintext
- JWT tokens signed with `python-jose`, include `sub` (username) and `exp`
- `get_current_user()` is the standard `Depends()` to inject user into endpoints
- Auth endpoints return Pydantic models: `Token(access_token=...)`, `UserOut(username=...)`
- HTTP status codes: 401 for bad credentials, 409 for duplicate user
## Usage in Routers
```python
from auth.dependencies import get_current_user
@router.get("/protected")
async def protected_route(current_user = Depends(get_current_user)):
...
```
## Anti-Patterns
- Don't hardcode secret keys — use `Settings` from environment
- Don't store tokens client-side without HttpOnly cookies
- Don't skip `response_model` on auth endpoints
- Don't leak whether username or password was wrong — always "incorrect username or password"
- Don't bypass `Depends(get_current_user)` for protected routes