Renamed all documentation files to follow kebab-case naming standard: - UPPERCASE files → lowercase (e.g., RBAC.md → rbac.md) - snake_case files → kebab-case (e.g., icons_guide.md → icons-guide.md) - SCREAMING_SNAKE_CASE → kebab-case (e.g., DATABASE_SETUP_GUIDE.md → database-setup-guide.md) Files renamed (15 total): API Documentation: - api/RBAC.md → api/rbac.md Architecture: - architecture/API_CONSOLIDATION_PROPOSAL.md → api-consolidation-proposal.md - architecture/API_MIGRATION_STATUS.md → api-migration-status.md Development: - development/AUTH_DEPENDENCIES_GUIDE.md → auth-dependencies-guide.md - development/CUSTOMER_AUTHENTICATION_IMPLEMENTATION.md → customer-authentication-implementation.md - development/CUSTOMER_AUTH_SUMMARY.md → customer-auth-summary.md - development/icons_guide.md → icons-guide.md Database Seeder: - database-seeder/DATABASE_INIT_GUIDE.md → database-init-guide.md - database-seeder/DATABASE_QUICK_REFERENCE_GUIDE.md → database-quick-reference-guide.md - database-seeder/DATABASE_SEEDER_DOCUMENTATION.md → database-seeder-documentation.md - database-seeder/MAKEFILE_DATABASE_SEEDER.md → makefile-database-seeder.md Error Rendering: - error-rendering/ERROR_RENDERING_DEVELOPER_DOCUMENTATION.md → error-rendering-developer-documentation.md - error-rendering/HTML_ERROR_RENDERING_FLOW_DIAGRAM.md → html-error-rendering-flow-diagram.md Getting Started: - getting-started/DATABASE_QUICK_REFERENCE.md → database-quick-reference.md - getting-started/DATABASE_SETUP_GUIDE.md → database-setup-guide.md Updates: - Updated all references in mkdocs.yml - Updated all cross-references in markdown files - Verified mkdocs builds without warnings or errors Standard: Use kebab-case (lowercase-with-hyphens) for all markdown files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
6.1 KiB
6.1 KiB
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:
# 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:
# 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:
# 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
- Identify route type: Is it an HTML page or API endpoint?
- Choose correct dependency:
- HTML page →
_from_cookie_or_header - API endpoint →
_api
- HTML page →
- Update import and usage
Example 1: HTML Page Route
Before:
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:
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:
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:
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
# 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 - Complete auth system docs
- Authentication Flow Diagrams - Visual flows
- Source code:
app/api/deps.py- Authentication dependency implementations