# 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/stores` | | `get_current_admin_optional` | Login pages | Cookie OR Header | Returns `None` instead of raising exception | ### Store Authentication | Dependency | Use Case | Accepts | Description | |------------|----------|---------|-------------| | `get_current_store_from_cookie_or_header` | HTML pages | Cookie OR Header | For store HTML routes like `/store/{code}/dashboard` | | `get_current_store_api` | API endpoints | Header ONLY | For store API routes like `/api/v1/store/{code}/products` | | `get_current_store_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 storefront account pages like `/storefront/account/dashboard` | | `get_current_customer_api` | API endpoints | Header ONLY | For storefront API routes like `/api/v1/storefront/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/stores.py from app.api.deps import get_current_admin_api @router.get("/api/v1/admin/stores") async def list_stores( current_user: User = Depends(get_current_admin_api), db: Session = Depends(get_db) ): return {"stores": [...]} ``` **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_store_user` | `get_current_store_from_cookie_or_header` | HTML pages | | `get_current_store_user` | `get_current_store_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/stores") def create_store(current_user: User = Depends(get_current_admin_user)): ... ``` **After:** ```python from app.api.deps import get_current_admin_api # ✅ @router.post("/api/v1/admin/stores") def create_store(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 ) # STORE from app.api.deps import ( get_current_store_from_cookie_or_header, # HTML pages get_current_store_api, # API endpoints get_current_store_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 - Source code: `app/api/deps.py` - Authentication dependency implementations