This is part of an ongoing series I am writing as I work my way through the modern web stack from a WordPress developer’s perspective. The series is aimed at WordPress veterans who, like me, have built things on the web for years and feel quietly behind the curve. The goal is broad literacy, not deep mastery. By the end you should be able to read any modern stack list and know what each piece is doing.
Each post comes with an audio companion (10-15 minutes, generated via NotebookLM) for gym or commute listening. Press play below if that suits you better than reading.
Hook
The reason most WordPress developers find modern auth confusing is that WordPress solved auth so completely, so long ago, that we forgot it was even a problem. wp_users, wp_usermeta, the login form, the password reset flow, the nonces, the capabilities system, the role check helpers: all there, all working, all invisible. You write if ( current_user_can('edit_posts') ) and you do not think about how the database represents that.
Modern frameworks ship with none of this. A blank Next.js project has no user table, no login page, no session cookie, no password reset link, no current_user helper. Auth is a feature you bring yourself. The good news is that doing this well has gotten dramatically better in the last three years. The bad news is that the vocabulary has multiplied at the same time: JWTs, OAuth, magic links, OIDC, Clerk, Auth.js, Supabase Auth, Lucia, custom sessions. None of them is exactly what wp_users was, and most of them want to replace several things at once.
This module is the auth orientation. What modern auth actually is, what changed since WordPress was designed, and which option to reach for in 2026 without overthinking it.
Core Concept
There are really three things to keep separate.
Identity is who the user is. An email address, a third-party identity (Google, GitHub, Apple), or a phone number. Identity is the rare-event part of auth: signup, password reset, social login, email verification.
Sessions are how the application remembers that this browser is logged in as a particular user. Sessions are the common-event part: every request needs to know who is making it. WordPress uses a session cookie that points to a row in wp_users. Modern stacks have more options here, which is where most of the new vocabulary lives.
Authorisation is what the user is allowed to do. WordPress has a built-in capability system (edit_posts, manage_options). Modern frameworks ship with nothing here; you build it yourself, usually with role columns in your database and check-functions in your code.
Most auth conversations confuse these three. “JWT” is a session mechanism, not an identity provider. “OAuth” is an identity flow, not a session strategy. “Clerk” is a service that handles identity, sessions, and (a bit of) authorisation in one bundle.
Sessions, the Modern Way
The traditional WordPress model is server-side sessions. A cookie holds an opaque token, the server looks the token up in the database, the database returns the user. This works well but requires a database hit on every request.
The two modern alternatives are:
Stateless JWTs (JSON Web Tokens). The cookie itself contains the user’s identity and claims, signed cryptographically. The server can verify the cookie without a database hit. Fast for serverless. Trade-off: you cannot revoke a JWT until it expires (typically 15 minutes to an hour for the access token, with a longer refresh token), and the token contains user data that gets larger as you add claims.
Server-side sessions with edge caching. Same idea as WordPress, but the session lookup goes to a fast cache (Redis or the database service’s built-in cache layer). The latency penalty is smaller than full DB lookups. This is what Auth.js defaults to.
In 2026 the trend is back toward server-side sessions for most apps, with JWTs reserved for cross-service or third-party API auth. The “JWTs for everything” era of 2018-2020 quietly ended once people noticed how hard revocation was.
Identity, the Modern Way
Most modern apps support multiple ways to log in:
- Email + password (still the most common)
- Magic link (email a one-time login URL, no password)
- Social login via OAuth (Google, GitHub, Apple, etc.)
- Passkeys (the new WebAuthn-based standard, gaining traction)
Each of these is a protocol. OAuth in particular is intricate; very few developers should implement it from scratch in 2026. The auth services and libraries below all wrap these flows so you do not have to.
The WordPress Analogue
Mental model: Modern auth services do what
wp_users+ the login page + nonce verification + capability checks all do together, but unbundled into pieces you compose yourself.The biggest mental shift: WordPress assumed every site needed every auth feature. Modern frameworks assume you pick the auth feature set per project. A blog might only need email logins for the author. A SaaS dashboard might need email + Google + GitHub + magic links + multi-factor auth + organisation invites. You scale the auth complexity to the project, instead of inheriting everything WordPress provided.
The Landscape
The main auth options in 2026:
| Option | Type | Best for | Strength | Trade-off |
|---|---|---|---|---|
| Auth.js (NextAuth) | Open-source library | Default for Next.js side projects | Free, runs in your own infrastructure, all major providers built-in | You manage the database; UI is bring-your-own |
| Clerk | Hosted service | SaaS where polished UX matters | Beautiful pre-built UI, social/password/MFA/passkeys, organisations | Costs money; users live in Clerk’s database, not yours |
| Supabase Auth | Bundled with Supabase | If you already use Supabase | Tight integration with Supabase RLS, generous free tier | Tied to Supabase; switching auth means switching DB |
| Lucia | Open-source library | Devs who want full control | Tiny, no opinions about UI, type-safe | More boilerplate, you build the pieces yourself |
| WorkOS / Auth0 / Cognito | Enterprise hosted | Apps with SSO/SAML/compliance needs | Enterprise features baked in (SAML, SCIM, audit logs) | Expensive; overkill for SaaS without enterprise customers |
| Custom session implementation | Roll your own | Specific compliance, weird requirements | Total control | Months of work, ongoing security maintenance |
For a default-stack 2026 project, the call usually comes down to:
- Clerk if you are a solo founder shipping a SaaS and want the most polished auth UX with the least work. The cost (starts at ~$25/mo, scales with users) is worth it for the time saved.
- Supabase Auth if you are already on Supabase and want everything in one place.
- Auth.js (NextAuth) if you want to avoid SaaS fees and are willing to spend a weekend setting it up properly.
- WorkOS when you have your first enterprise customer asking for SSO.
What This Changes for WordPress People
Three practical wins.
The first is that auth becomes deliberate. You stop assuming “WordPress handles login” and start asking “what auth does this project actually need?” Some sites need none (static marketing). Some need basic email login (a small SaaS). Some need everything (a multi-tenant B2B platform). Choosing the right auth tool per project saves time and avoids over-engineering.
The second is that hybrid sites get cleaner. If you build a Next.js app alongside a WordPress site, you do not have to share auth between them. The marketing site can stay WordPress with WP login for editors. The application can use Clerk or Auth.js with its own user store. They co-exist without overlap.
The third is the security posture improves. WordPress’s auth has been battle-tested but is also a known target. Bots scan WP login pages constantly. Moving the application’s auth to a modern service (or a properly configured Auth.js install) reduces your attack surface and gives you better tooling for things like rate limiting, MFA, and audit logs.
Watch Out
A few traps that catch developers new to modern auth.
JWTs are not magic. They feel cool because they remove the database lookup, but they introduce revocation problems, claim-size problems, and clock-sync problems. Use them where they make sense (cross-service auth, mobile apps, short-lived access tokens), not as a default replacement for sessions.
OAuth implementations need care. Implementing OAuth correctly is hard. Libraries like Auth.js handle it; rolling your own is a security risk unless you know what you are doing. The classic mistake is accepting the OAuth callback without verifying the state parameter, opening a CSRF hole.
Auth services lock in user data. If you use Clerk, your user records live in Clerk. Exporting them later is possible but requires planning. The same goes for Supabase Auth or Auth0. Read the data portability docs of any service before committing.
Password storage is the table stakes. Whatever you do for auth, hashing passwords with bcrypt or argon2 is non-negotiable. WordPress uses phpass (an older bcrypt variant). Modern frameworks default to argon2. If you ever see a project storing passwords with MD5 or SHA1, that is a security incident waiting to happen.
Email deliverability quietly matters. Magic links and password resets only work if your emails arrive. Almost every auth project hits a deliverability problem in the first month. Set up a transactional email provider (Resend, Postmark, AWS SES) and authenticate your domain (SPF, DKIM, DMARC) on day one.
Going Deeper
If you want to develop real intuition about which auth tool to reach for, a few resources worth your time.
YouTube, gym or commute friendly:
- “Auth.js in 100 Seconds” by Fireship, then “Auth.js v5 Tutorial” by Code With Antonio (~1 hour). Orientation, then the full setup walkthrough.
- “Clerk Authentication Tutorial” on the Clerk channel (~30 min). Worth watching because Clerk’s onboarding sets the bar for auth DX.
Official docs worth bookmarking:
- Auth.js docs. Pay particular attention to the providers section; configuring Google or GitHub OAuth correctly takes a few tries.
- Clerk docs. Strong onboarding, clear pricing. Worth a skim even if you go with Auth.js.
- Supabase Auth docs. Especially the Row Level Security pages, where Supabase’s auth model gets interesting.
Next post in the series leaves the data layer behind and looks at hosting. Vercel, Netlify, Fly.io, Cloudflare Pages, Railway, Render: what each one actually is, and when to reach for which.

Leave a Reply