Web Auth - Web Authentication & Session Management
Domain: Web Auth
Location: api/nextango/apps/web_auth/
Mount: /auth/ (api/nextango/urls.py:155)
Last Updated: 2026-07-09
Overview
The web_auth app provides session-based authentication for web clients: the dashboard and the storefront. It covers email-first login (password or OTP), customer registration, password recovery, session lifecycle, and profile editing. Sessions are Django session cookies backed by a WebSession database record, not JWT or bearer tokens.
PIN login for POS terminals lives in the users app (authenticate_pin_login, consumed by pos_gateway) and is out of scope for this domain.
Documentation Quick Links
| File | Description |
|---|---|
| models.md | WebSession, OTPCode, SessionPermission models |
| serializers.md | Read-only response serializers and registration input serializers |
| views.md | All 14 authentication API endpoints |
| services.md | OTPService, RateLimitService, SessionService, RegistrationService |
| signals.md | Why web_auth uses service methods instead of Django signals |
| authentication.md | WebSessionAuthentication DRF class |
| middleware.md | WebSessionAuthMiddleware and IPBlockingMiddleware |
| examples.md | curl examples for each auth flow |
Key Features
Authentication flows
- Session-based authentication using Django session cookies, not JWT or bearer tokens
- Email-first entry point that routes the client to a password or OTP path
- OTP verification with 6-digit codes and a 5-minute expiration
- Password recovery through a non-consuming validate step followed by a consuming reset step
- Guest demo sessions that do not require a user account
- Customer registration with OTP verification and automatic guest-cart merge
Security
- Progressive OTP rate limiting: 30 seconds, then 5 minutes, then 1 hour
- Progressive account lockout on failed attempts: 15 minutes, 1 hour, 2 hours
- IP-level protection against request flooding and authentication failure spam
- Dev-mode mock superuser for guest sessions, active only when
DEBUG=True - Email delivery through Resend with Django SMTP as a fallback
IP protection rules (IPBlockingMiddleware)
- More than 30 requests from one IP in 1 second blocks that IP for 1 hour
- More than 5 failed authentications (401 responses) from one IP in 10 seconds blocks it for 10 minutes
- More than 20 failed authentications from one IP in 1 minute also blocks it for 10 minutes
API Endpoints
All paths are mounted under /auth/ at the application root (no /api/ prefix).
| Endpoint | Method | Description |
|---|---|---|
/auth/check-email/ | POST | Determine whether the email should log in with a password or an OTP |
/auth/login/ | POST | Password login, OTP initiation, or dev-mode bypass |
/auth/verify-otp/ | POST | Verify OTP and create a session, or prompt for password creation |
/auth/set-password/ | POST | Set a password after OTP verification and create a session |
/auth/register/initiate/ | POST | Start customer registration, sends OTP |
/auth/register/verify/ | POST | Complete registration with OTP, creates User and Customer role |
/auth/register/resend-otp/ | POST | Resend the registration OTP |
/auth/forgot-password/ | POST | Start password recovery, sends OTP |
/auth/verify-recovery-otp/ | POST | Validate the recovery OTP without consuming it |
/auth/reset-password/ | POST | Consume the recovery OTP and set a new password |
/auth/session/ | GET | Check current session status and permissions |
/auth/logout/ | POST | Terminate the session |
/auth/update-email/initiate/ | POST | Send an OTP to a new email address for an email change |
/auth/users/me/ | PATCH | Update the current user's name or email |
Full endpoint documentation: views.md
Architecture Highlights
Service layer, not signals
web_auth uses explicit service classes (OTPService, RateLimitService, SessionService, RegistrationService) instead of Django signals. Authentication steps such as rate-limit checks, OTP verification, and session creation have a strict order, and service methods make that order explicit in the view code rather than hidden in signal handlers.
Read more: signals.md
Middleware and DRF authentication work together
WebSessionAuthMiddleware validates the session once per request and attaches it to request.web_session. WebSessionAuthentication (a DRF authentication class) reuses that validation when present, or validates directly if the middleware did not run.
Read more: authentication.md, middleware.md
Related Domains
- Users: User model, roles, and PIN login (
authenticate_pin_login) - Web Commerce: Cart and checkout, resolves identity via WebSession
- POS Gateway: Consumes PIN login from the users app, not web_auth
Key Architectural Decisions
- Session-based authentication over JWT, for simpler revocation on the web dashboard and storefront
- Service layer over signals, for explicit and testable authentication logic
- Progressive rate limiting and lockout, escalating with repeated failures
- Email-first flow that routes to password or OTP from a single entry point
- Cart-session continuity via
cart_token_hash, a cookie-independent credential for guest carts
Next Steps
- models.md: data structures
- views.md: API endpoints
- authentication.md: DRF integration
- middleware.md: session and IP protection