Web Auth Middleware
Location: api/nextango/apps/web_auth/
Last Updated: 2026-07-09
Overview
Two middleware classes protect API endpoints. WebSessionAuthMiddleware (middleware.py) enforces session authentication for requests coming from a web browser. IPBlockingMiddleware (ip_blocking.py) blocks IPs that flood requests or spam authentication failures. Both are disabled entirely when settings.DEBUG is True.
WebSessionAuthMiddleware
Validates that web-browser requests to API endpoints carry a valid WebSession, distinguishing browser traffic from API clients (mobile apps, integrations, Postman, curl) by Origin, Referer, and User-Agent.
Skips (no session check applied):
/auth/*: the public auth endpoints documented in views.md/pos/auth/*: POS terminal login/admin/*: has its ownAdminOTPAuthMiddleware/static/*,/media/*,/health/*/integrations/*,/webhooks/*- any path containing
/send-receipt/, since the transaction id itself serves as access control /pos/health/*- any request carrying an
Authorizationheader, treated as token auth, not session auth
For requests identified as web-browser origin that reach none of the skip conditions, the middleware calls SessionService.validate_session(request). An invalid or missing session returns 401 with {"error": "authentication_required", "message": "...", "auth_url": "/auth/login/"}. A valid session is then checked against SessionService.get_permissions(session.session_type): the request path must match a rule's endpoint_pattern (regex) and the request method must be in that rule's http_methods (or the rule allows "*"). No match returns 403 with {"error": "forbidden", "message": "...", "session_type": "..."}.
On success the middleware sets request.web_session to the validated session, and sets request.user to session.user when the session has a linked user.
Web-origin detection checks Origin and Referer against a list of known web domains (production and local dev ports), then falls back to User-Agent browser indicators (Mozilla, Chrome, Safari, Firefox, Edge) when neither header is present, excluding known API-client user agents (PostmanRuntime, curl, python-requests, axios).
IPBlockingMiddleware
Tracks request rate and authentication failures per client IP and blocks abusive IPs, independent of any per-account rate limiting in RateLimitService.
Rules:
- More than 30 requests from one IP within 1 second blocks that IP for 1 hour (
request_flooding) - More than 5 failed authentications (401 responses) from one IP within 10 seconds blocks it for 10 minutes (
auth_spam) - More than 20 failed authentications from one IP within 1 minute also blocks it for 10 minutes (
auth_spam)
Skips: /auth/* (has its own RateLimitService), /admin/*, OPTIONS requests (CORS preflight), and internal Docker network IPs (10.0.*, 172.*, 127.0.0.1).
Client IP is taken from the first entry in X-Forwarded-For if present, otherwise REMOTE_ADDR. Blocked IPs receive 429 with {"error": "blocked", "message": "..."}. On a successful login, clear_auth_spam_block(ip) removes an auth_spam block and its counters for that IP, but never touches a request_flooding block, which persists regardless of subsequent successful authentication.
Middleware Order
Both middleware sit after SessionMiddleware (they need request.session). IPBlockingMiddleware should run before WebSessionAuthMiddleware, so abusive IPs are rejected before any session lookup.
Production requirement: DEBUG=False is required for either middleware to enforce anything; both are complete no-ops under DEBUG=True.