# Authentication Quick Reference **Version 1.0** | One-page reference for developers --- ## Function Cheat Sheet ### For HTML Pages (accept cookie OR header) ```python from app.api.deps import ( get_current_admin_from_cookie_or_header, get_current_vendor_from_cookie_or_header, get_current_customer_from_cookie_or_header ) from models.database.customer import Customer # Admin page @router.get("/admin/dashboard") def admin_page(user: User = Depends(get_current_admin_from_cookie_or_header)): pass # Vendor page @router.get("/vendor/{code}/dashboard") def vendor_page(user: User = Depends(get_current_vendor_from_cookie_or_header)): pass # Customer page - NOTE: Returns Customer, not User! @router.get("/shop/account/dashboard") def customer_page(customer: Customer = Depends(get_current_customer_from_cookie_or_header)): pass # customer.id, customer.email, customer.vendor_id ``` ### For API Endpoints (header only - better security) ```python from app.api.deps import ( get_current_admin_api, get_current_vendor_api, get_current_customer_api ) from models.database.customer import Customer # Admin API @router.post("/api/v1/admin/vendors") def admin_api(user: User = Depends(get_current_admin_api)): pass # Vendor API @router.post("/api/v1/vendor/products") def vendor_api(user: User = Depends(get_current_vendor_api)): pass # user.token_vendor_id for vendor context # Customer API - NOTE: Returns Customer, not User! @router.post("/api/v1/shop/orders") def customer_api(request: Request, customer: Customer = Depends(get_current_customer_api)): pass # customer.id, request.state.vendor validated to match ``` --- ## Three Authentication Contexts | Context | Cookie | Path | Role | Routes | |---------|--------|------|------|--------| | **Admin** | `admin_token` | `/admin` | `admin` | `/admin/*` | | **Vendor** | `vendor_token` | `/vendor` | `vendor` | `/vendor/*` | | **Customer** | `customer_token` | `/shop` | `customer` | `/shop/account/*` | --- ## Access Control Matrix | User | Admin Portal | Vendor Portal | Shop Catalog | Customer Account | |------|--------------|---------------|--------------|------------------| | Admin | ✅ | ❌ | ✅ (view) | ❌ | | Vendor | ❌ | ✅ | ✅ (view) | ❌ | | Customer | ❌ | ❌ | ✅ (view) | ✅ | | Anonymous | ❌ | ❌ | ✅ (view) | ❌ | --- ## Login Endpoints ```bash # Admin POST /api/v1/admin/auth/login Body: {"username": "...", "password": "..."} # Vendor POST /api/v1/vendor/auth/login Body: {"username": "...", "password": "..."} # Customer POST /api/v1/public/vendors/{vendor_id}/customers/login Body: {"username": "...", "password": "..."} ``` **Response:** ```json { "access_token": "eyJ0eXAi...", "token_type": "Bearer", "expires_in": 3600, "user": {...} } ``` Plus HTTP-only cookie is set automatically. --- ## Frontend Patterns ### Login (Store Token) ```javascript const response = await fetch('/api/v1/admin/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await response.json(); // Cookie set automatically // Optionally store for API calls localStorage.setItem('token', data.access_token); // Navigate (cookie automatic) window.location.href = '/admin/dashboard'; ``` ### API Call (Use Token) ```javascript const token = localStorage.getItem('token'); const response = await fetch('/api/v1/admin/vendors', { headers: { 'Authorization': `Bearer ${token}` } }); ``` ### Logout ```javascript await fetch('/api/v1/admin/auth/logout', { method: 'POST' }); localStorage.removeItem('token'); window.location.href = '/admin/login'; ``` --- ## Testing Commands ### curl Examples ```bash # Login TOKEN=$(curl -X POST http://localhost:8000/api/v1/admin/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin123"}' \ | jq -r '.access_token') # Authenticated request curl http://localhost:8000/api/v1/admin/vendors \ -H "Authorization: Bearer $TOKEN" ``` ### Check Cookie in Browser ```javascript // In DevTools console document.cookie.split(';').forEach(c => console.log(c.trim())); ``` ### Decode JWT ```javascript function parseJwt(token) { return JSON.parse(atob(token.split('.')[1])); } console.log(parseJwt(localStorage.getItem('token'))); ``` --- ## Common Errors | Error | Meaning | Solution | |-------|---------|----------| | `INVALID_TOKEN` | No token or invalid | Re-login | | `TOKEN_EXPIRED` | Token expired | Re-login | | `ADMIN_REQUIRED` | Need admin role | Use correct account | | `INSUFFICIENT_PERMISSIONS` | Wrong role for route | Use correct portal | | `USER_NOT_ACTIVE` | Account disabled | Contact admin | --- ## Security Rules 1. ✅ **HTML pages** use `*_from_cookie_or_header` functions 2. ✅ **API endpoints** use `*_api` functions 3. ✅ **Admins** cannot access vendor/customer portals 4. ✅ **Vendors** cannot access admin/customer portals 5. ✅ **Customers** cannot access admin/vendor portals 6. ✅ **Public shop** (`/shop/products`) needs no auth 7. ✅ **Customer accounts** (`/shop/account/*`) need auth --- ## Cookie Security All cookies have: - ✅ `HttpOnly=true` - JavaScript cannot read (XSS protection) - ✅ `Secure=true` - HTTPS only (production) - ✅ `SameSite=Lax` - CSRF protection - ✅ Path restriction - Context isolation --- ## Quick Debug 1. **Auth not working?** - Check DevTools → Application → Cookies - Verify cookie name and path match route - Check token not expired 2. **Cross-context access denied?** - This is intentional security - Use correct portal for your role 3. **API call fails but page loads?** - API needs `Authorization` header - Page uses cookie (automatic) - Add header to API calls --- ## File Locations ``` app/api/ ├── deps.py # All auth functions here ├── v1/ ├── admin/auth.py # Admin login ├── vendor/auth.py # Vendor login └── public/vendors/auth.py # Customer login ``` --- ## Environment Variables ```bash JWT_SECRET_KEY=your-secret-key JWT_ALGORITHM=HS256 JWT_EXPIRATION=3600 # 1 hour ENVIRONMENT=production ``` --- **Full Documentation:** See [Authentication System Documentation](authentication.md) **Questions?** Contact backend team --- **Print this page for quick reference!**