Authentication flows of Django, Laravel and WordPress

Lesson#2 of 3 in topic Theory

How do they work in general?

Django relies on session cookies and middleware.

Laravel is very similar but adds Sanctum/Passport for API tokens on top.

WordPress is the most opaque — it mixes nonces, cookies, and REST auth in ways that often surprise developers.

Django

Django's auth is built around its middleware stack — every request passes through SecurityMiddlewareSessionMiddlewareAuthenticationMiddleware in order before hitting your view. The authenticate() call runs configured backends (default: ModelBackend against the DB), and login() cycles the session ID to prevent session fixation attacks.




Laravel

Laravel shares the same session-cookie model but adds a dedicated Auth facade and first-party API token packages.


Laravel splits cleanly into a web path (session + remember-me cookie) and an API path (Sanctum bearer token, stored hashed in the DB). Auth::attempt() fires an Authenticated event regardless of path, which is a good hook for audit logging.

WordPress

WordPress is the most complex — it has three distinct auth mechanisms running in parallel.


WordPress runs three auth mechanisms in parallel, which is why it can feel chaotic:

  • Cookie auth — the classic browser flow. wp_set_auth_cookie() issues an HMAC-signed httpOnly cookie, validated on every page load via wp_validate_auth_cookie().
  • REST nonce — for JS in the browser talking to /wp-json/. A short-lived nonce (24h, scoped per action) is embedded in the page and sent as X-WP-Nonce. This is not CSRF protection by itself — it pairs with cookie auth.
  • Application Passwords — added in WP 5.6 for external API clients (mobile apps, integrations). Sent as HTTP Basic Auth, stored hashed in user meta. Completely separate from the login password.

All three paths funnel into current_user_can() at the end, which is where WordPress's capability/role system enforces what the authenticated user is actually allowed to do.