This is part of a series on the modern web stack, written from a WordPress developer’s seat for people who’ve built on the web for years and still hit stack terms they can’t define. The goal is literacy, enough that you can read any stack list and know what each piece does.
Each post has a 10-15 minute audio companion, generated with NotebookLM, for the gym or the commute.
WordPress solved auth so completely, so long ago, that most of us forgot it was a problem. wp_users, wp_usermeta, the login form, the password reset flow, nonces, capabilities, the role check helpers: all there, all working, all invisible. You write if ( current_user_can('edit_posts') ) and never think about how the database represents that.
A blank Next.js project has none of it. No user table, no login page, no session cookie, no password reset link, no current_user helper. You bring auth yourself. Doing that well has gotten much easier in the last three years, while the vocabulary multiplied: JWTs, OAuth, magic links, OIDC, Clerk, Auth.js, Supabase Auth, Lucia, custom sessions. None of them is exactly what wp_users was, and most want to replace several things at once.
This post covers what modern auth is, what changed since WordPress was designed, and which option to reach for in 2026. If Next.js is still new to you, Next.js as the WordPress of React is the place to start.
Three Separate Jobs
Auth is three things, and most of the confusion comes from blending them.
Identity
Identity is who the user is: an email address, a third-party account (Google, GitHub, Apple) or a phone number. It’s the rare-event part of auth: signup, password reset, social login, email verification.
Sessions
A session is how the application remembers that this browser is logged in as a particular user. It’s the common-event part, because every request has to know who’s making it. WordPress uses a session cookie tied to a user row. Modern stacks offer more options here, which is where most of the new vocabulary lives.
Authorization
Authorization is what the user is allowed to do. WordPress has a built-in capability system (edit_posts, manage_options). Modern frameworks ship nothing equivalent, so you build it, usually with role columns in your database and check functions in your code.
“JWT” is a session mechanism and “OAuth” is an identity flow. Clerk is a service that handles identity, sessions and a bit of authorization in one bundle. Keeping the three jobs apart makes most auth docs readable.
Sessions, the modern way
The traditional WordPress model is a server-side session. A cookie holds an opaque token, the server looks it up in the database, and the database returns the user. It works well, but it costs a database hit on every request.
A stateless JWT (JSON Web Token) puts the user’s identity and claims in the cookie itself, signed cryptographically, so the server can verify it without touching the database. That suits serverless. The catch is revocation: you can’t invalidate a JWT until it expires (typically 15 minutes to an hour for the access token, with a longer-lived refresh token), and the token grows as you add claims.
The other option is the WordPress approach with a faster lookup: the session goes to a cache like Redis or the database service’s built-in cache layer, which cuts most of the latency. 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 and third-party API auth. The “JWTs for everything” era of 2018-2020 ended once people hit the revocation problem. Serverless and edge is why the stateless option exists at all.
Identity, the modern way
Most modern apps offer several ways to log in:
- Email and password, still the most common
- Magic links, a one-time login URL sent by email
- Social login through OAuth (Google, GitHub, Apple)
- Passkeys, the WebAuthn-based standard that’s gaining traction
Each is a protocol, and OAuth in particular has a lot of moving parts. Very few developers should write it from scratch in 2026. The libraries and services below wrap these flows for you.
The WordPress Analogue
Modern auth services do what
wp_users, the login page, nonce verification and capability checks do together, but split into pieces you compose yourself.
WordPress assumed every site needed every auth feature. Modern frameworks let you pick per project. A blog might need email login for one author. A SaaS dashboard might need email, Google, GitHub, magic links, multi-factor auth and organization invites. You scale the auth to the project instead of inheriting everything.
Your 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 on 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 | Pre-built UI, social login, passwords, MFA and passkeys, organizations | Costs money; users live in Clerk’s database, not yours |
| Supabase Auth | Bundled with Supabase | Projects already on 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 or compliance needs | Enterprise features built in (SAML, SCIM, audit logs) | Expensive; overkill without enterprise customers |
| Roll your own | Custom | Specific compliance or unusual requirements | Total control | Months of work, ongoing security maintenance |
For a default-stack 2026 project, the call usually comes down to this:
- Clerk for a solo founder shipping a SaaS who wants the most polished auth UX with the least work. The cost (from about $25/mo, scaling with users) pays for itself in saved time.
- Supabase Auth if you’re already on Supabase and want everything in one place. Beyond shared MySQL covers that side.
- Auth.js if you want to avoid SaaS fees and can spend a weekend setting it up properly.
- WorkOS when your first enterprise customer asks for SSO.
What This Changes for WordPress People
Auth becomes deliberate. You stop assuming “WordPress handles login” and ask what auth the project needs. Some sites need none, like a static marketing site. Some need basic email login, like a small SaaS. Some need everything, like a multi-tenant B2B platform. Picking the right tool per project saves time and avoids over-engineering.
Hybrid sites get cleaner. If you build a Next.js app alongside a WordPress site, the two don’t have to share auth. The marketing site stays WordPress with WP login for editors, and the application uses Clerk or Auth.js with its own user store. How the pieces wire up shows where that sits in a full request.
Security posture improves too. WordPress auth is battle-tested but also a known target, and bots scan WP login pages constantly. Moving the application’s auth to a modern service, or a properly configured Auth.js install, shrinks your attack surface and gives you better tooling for rate limiting, MFA and audit logs.
Where Auth Goes Wrong
JWTs are not magic
They feel clever because they skip the database lookup, but they bring revocation, claim-size and clock-sync problems. Use them for cross-service auth, mobile apps and short-lived access tokens, and keep sessions as the default.
OAuth needs care
Writing OAuth yourself is a security risk unless you know the spec well. Auth.js handles it. The classic mistake is accepting the OAuth callback without verifying the state parameter, which opens a CSRF hole.
Auth services hold your user data
With Clerk, your user records live in Clerk. Exporting them later is possible but takes planning, and the same goes for Supabase Auth and Auth0. Read the data portability docs before committing.
Password storage
Hash passwords with bcrypt or argon2, no exceptions. WordPress uses phpass, an older bcrypt-style scheme, and modern frameworks default to argon2. A project storing passwords with MD5 or SHA1 is a security incident waiting to happen.
Email deliverability
Magic links and password resets only work if the emails arrive, and almost every auth project hits a deliverability problem in its first month. Set up a transactional email provider (Resend, Postmark, AWS SES) and authenticate your domain with SPF, DKIM and DMARC on day one.
Get a Feel for the Auth Options
A few resources for building intuition about which tool to reach for.
YouTube
- “Auth.js in 100 Seconds” by Fireship, then “Auth.js v5 Tutorial” by Code With Antonio (about an hour). Orientation first, then the full setup walkthrough.
- “Clerk Authentication Tutorial” on the Clerk channel (about 30 minutes). Clerk’s onboarding sets the bar for auth DX.
Official docs
- Auth.js docs. Start with the providers section; configuring Google or GitHub OAuth correctly takes a few tries.
- Clerk docs. Strong onboarding and clear pricing, worth a skim even if you go with Auth.js.
- Supabase Auth docs. The Row Level Security pages are where Supabase’s auth model gets interesting.
The next post leaves the data layer behind and looks at hosting: Vercel, Netlify, Fly.io, Cloudflare, Railway, Render, what each one is and when to reach for which. It’s Hosting beyond Kinsta.

Leave a Reply