From ac1017928cb0b77844a1b390bfbbdc1bb1a9b2d1 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Sat, 22 Nov 2025 16:03:03 +0100 Subject: [PATCH] docs: add authentication dependencies guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive guide explaining when to use each authentication dependency: - get_current_admin_from_cookie_or_header vs get_current_admin_api - get_current_vendor_from_cookie_or_header vs get_current_vendor_api - get_current_customer_from_cookie_or_header vs get_current_customer_api Key distinctions: - HTML pages (templates) → use _from_cookie_or_header (accepts cookies) - API endpoints (JSON) → use _api (header-only, no cookies, CSRF-safe) - Login pages → use _optional (returns None instead of exception) Includes: - Complete reference table - When to use which dependency - Migration guide from old names - Code examples for each scenario - Quick reference cheat sheet This clarifies the naming change from get_current_admin_user to the more specific variants and helps developers choose the right dependency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/development/AUTH_DEPENDENCIES_GUIDE.md | 191 ++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 192 insertions(+) create mode 100644 docs/development/AUTH_DEPENDENCIES_GUIDE.md diff --git a/docs/development/AUTH_DEPENDENCIES_GUIDE.md b/docs/development/AUTH_DEPENDENCIES_GUIDE.md new file mode 100644 index 00000000..225b946c --- /dev/null +++ b/docs/development/AUTH_DEPENDENCIES_GUIDE.md @@ -0,0 +1,191 @@ +# Authentication Dependencies Guide + +## Overview + +FastAPI routes use different authentication dependencies based on whether they serve **HTML pages** or **API endpoints**. + +## Available Dependencies + +### Admin Authentication + +| Dependency | Use Case | Accepts | Description | +|------------|----------|---------|-------------| +| `get_current_admin_from_cookie_or_header` | HTML pages | Cookie OR Header | For admin HTML routes like `/admin/dashboard` | +| `get_current_admin_api` | API endpoints | Header ONLY | For admin API routes like `/api/v1/admin/vendors` | +| `get_current_admin_optional` | Login pages | Cookie OR Header | Returns `None` instead of raising exception | + +### Vendor Authentication + +| Dependency | Use Case | Accepts | Description | +|------------|----------|---------|-------------| +| `get_current_vendor_from_cookie_or_header` | HTML pages | Cookie OR Header | For vendor HTML routes like `/vendor/{code}/dashboard` | +| `get_current_vendor_api` | API endpoints | Header ONLY | For vendor API routes like `/api/v1/vendor/{code}/products` | +| `get_current_vendor_optional` | Login pages | Cookie OR Header | Returns `None` instead of raising exception | + +### Customer Authentication + +| Dependency | Use Case | Accepts | Description | +|------------|----------|---------|-------------| +| `get_current_customer_from_cookie_or_header` | HTML pages | Cookie OR Header | For shop account pages like `/shop/account/dashboard` | +| `get_current_customer_api` | API endpoints | Header ONLY | For shop API routes like `/api/v1/shop/cart` | +| `get_current_customer_optional` | Login pages | Cookie OR Header | Returns `None` instead of raising exception | + +## When to Use Which? + +### Use `_from_cookie_or_header` for HTML Pages + +HTML pages that render templates and are accessed by browsers: + +```python +# app/routes/admin_pages.py +from app.api.deps import get_current_admin_from_cookie_or_header + +@router.get("/admin/dashboard", response_class=HTMLResponse) +async def admin_dashboard( + request: Request, + current_user: User = Depends(get_current_admin_from_cookie_or_header) +): + return templates.TemplateResponse("admin/dashboard.html", {...}) +``` + +**Why?** Browsers automatically send cookies, making this seamless for page navigation. + +### Use `_api` for API Endpoints + +JSON API endpoints that are called by JavaScript: + +```python +# app/api/v1/admin/vendors.py +from app.api.deps import get_current_admin_api + +@router.get("/api/v1/admin/vendors") +async def list_vendors( + current_user: User = Depends(get_current_admin_api), + db: Session = Depends(get_db) +): + return {"vendors": [...]} +``` + +**Why?** +- **Security**: API endpoints should NOT accept cookies (prevents CSRF attacks) +- **Explicit**: JavaScript must explicitly set Authorization header +- **Stateless**: API calls are stateless and don't rely on browser cookies + +### Use `_optional` for Login Pages + +Login pages that redirect if already authenticated: + +```python +# app/routes/admin_pages.py +from app.api.deps import get_current_admin_optional + +@router.get("/admin/login", response_class=HTMLResponse) +async def admin_login_page( + request: Request, + current_user: Optional[User] = Depends(get_current_admin_optional) +): + if current_user: + return RedirectResponse("/admin/dashboard") + return templates.TemplateResponse("admin/login.html", {...}) +``` + +**Why?** Avoids showing login page to already-authenticated users. + +## Migration Guide + +### Old vs New Names + +The authentication dependencies were renamed for clarity: + +| ❌ Old Name (REMOVED) | ✅ New Name | Type | +|----------------------|-------------|------| +| `get_current_admin_user` | `get_current_admin_from_cookie_or_header` | HTML pages | +| `get_current_admin_user` | `get_current_admin_api` | API endpoints | +| `get_current_vendor_user` | `get_current_vendor_from_cookie_or_header` | HTML pages | +| `get_current_vendor_user` | `get_current_vendor_api` | API endpoints | + +### How to Update Your Code + +1. **Identify route type**: Is it an HTML page or API endpoint? +2. **Choose correct dependency**: + - HTML page → `_from_cookie_or_header` + - API endpoint → `_api` +3. **Update import and usage** + +#### Example 1: HTML Page Route + +**Before:** +```python +from app.api.deps import get_current_admin_user # ❌ Doesn't exist + +@router.get("/admin/settings") +def settings_page(current_user: User = Depends(get_current_admin_user)): + ... +``` + +**After:** +```python +from app.api.deps import get_current_admin_from_cookie_or_header # ✅ + +@router.get("/admin/settings") +def settings_page( + current_user: User = Depends(get_current_admin_from_cookie_or_header) +): + ... +``` + +#### Example 2: API Endpoint + +**Before:** +```python +from app.api.deps import get_current_admin_user # ❌ Doesn't exist + +@router.post("/api/v1/admin/vendors") +def create_vendor(current_user: User = Depends(get_current_admin_user)): + ... +``` + +**After:** +```python +from app.api.deps import get_current_admin_api # ✅ + +@router.post("/api/v1/admin/vendors") +def create_vendor(current_user: User = Depends(get_current_admin_api)): + ... +``` + +## Quick Reference + +```python +# All available in app.api.deps + +# ADMIN +from app.api.deps import ( + get_current_admin_from_cookie_or_header, # HTML pages + get_current_admin_api, # API endpoints + get_current_admin_optional, # Login pages +) + +# VENDOR +from app.api.deps import ( + get_current_vendor_from_cookie_or_header, # HTML pages + get_current_vendor_api, # API endpoints + get_current_vendor_optional, # Login pages +) + +# CUSTOMER +from app.api.deps import ( + get_current_customer_from_cookie_or_header, # HTML pages + get_current_customer_api, # API endpoints + get_current_customer_optional, # Login pages +) + +# GENERIC (any authenticated user) +from app.api.deps import get_current_user # Header-only, any role +``` + +## See Also + +- [Authentication Documentation](../api/authentication.md) - Complete auth system docs +- [Authentication Flow Diagrams](../api/authentication-flow-diagrams.md) - Visual flows +- [API Dependencies](../app/api/deps.py) - Source code diff --git a/mkdocs.yml b/mkdocs.yml index a7c7e5ab..a090636e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -95,6 +95,7 @@ nav: - Development: - Icons Guide: development/icons_guide.md - Naming Conventions: development/naming-conventions.md + - Auth Dependencies Guide: development/AUTH_DEPENDENCIES_GUIDE.md - Database Migrations: development/database-migrations.md - Database Seeder: - Documentation: development/database-seeder/DATABASE_SEEDER_DOCUMENTATION.md