Eleven lessons gave you the whole map. This one makes it a build. Two skills close the mission: a decision framework for picking which methods to combine for a given app — and a complete, running Express auth app on your machine that wires the pieces together. By the end you'll have logged into something you can read top to bottom and modify with confidence.
🎯 Mission: a mental model of modern auth + the ability to wire it into a real appThere is no single "best" auth — there's the right combination for your app's clients, threat model, and team. You choose along a few axes (who are your clients? how sensitive is the data? do you want to own credentials at all?), then assemble from the building blocks you now know. The wiring is short and boring once the decisions are made — and that's the goal: decisions deliberate, implementation unremarkable.
Don't start from "which library?" Start from these questions. Each one steers you toward specific lessons.
| Question | If… | Lean toward |
|---|---|---|
| Who are your clients? | One web app, your domain | Session id in an HttpOnly cookie (L1–2) |
| Mobile / SPA / third-party APIs | Tokens: short access + rotating refresh (L3, L7) | |
| Do you want to own passwords? | No (and users have Google/GitHub) | OAuth2 + OIDC — "Sign in with X" (L5–6) |
| Yes / need first-party accounts | Password (Argon2id) or passwordless (L4, L8) | |
| How sensitive is the data? | Low–medium | Single strong factor + optional TOTP (L10) |
| High (money, health, admin) | Passkeys (L9) or enforced MFA + step-up (L10) | |
| What's your phishing tolerance? | Must resist phishing | Passkeys — the only phishing-proof option (L9) |
| Team capacity? | Small / don't want to own it | A provider (Auth0/Clerk/Cognito) — same concepts, their plumbing |
Session cookie (L2) + password (Argon2id) or magic link (L4/L8) + optional TOTP (L10). Add "Sign in with Google" (L6) for convenience. Reset/verify flows per L11. The boring, correct default.
OAuth2 + PKCE (L6, no client secret) → short access token + rotating refresh (L7). API verifies the access token's signature with a pinned alg (L3). No cookies.
Passkeys (L9, phishing-proof) as primary, backup codes for recovery (L11), step-up re-auth on dangerous actions (L10). Short sessions, "log out everywhere" (L7).
Notice each is just a combination of blocks you've already built and run. There's no twelfth secret technique — mastery is knowing which to combine and why.
Every design in this course shares one skeleton. Internalize it and any auth system is legible:
I built a full, working Express auth app on your machine — signup with hashed passwords, login, a CSRF-protected session, a guarded page, and logout. Dependencies are installed and it's smoke-tested.
# in your terminal: cd ~/projects/learn/public/courses/auth/practice/capstone-app npm start # → open http://localhost:3000 and actually sign up + log in
POST /signup (valid CSRF) → 302 /account ← hashed pw stored, session started GET /account (with session) → 🔒 Protected page GET /account (no session) → 302 /login ← the guard works POST /signup (bad CSRF) → 403 Forbidden ← CSRF defense worksOpen
server.js — it's ~110 lines and every block is tagged with the lesson it came from: bcrypt.hash (L4), the session() cookie flags (L2), the double-submit checkCsrf (L2), req.session.userId = … (the handoff), requireAuth (the guard), session.regenerate on login (fixation defense, L2), and session.destroy for logout (L7). Nothing in it is new to you. That's the whole point — you can read and modify a real auth system now.HttpOnly + Secure (prod) + SameSite=Lax; real session store, not MemoryStore; __Host- prefix.
Argon2id (or bcrypt ≥10); generic login error; rate-limit + lockout; check breached-password lists.
Pin algorithms; short access + rotating refresh; reuse detection; "log out everywhere."
SameSite + a token on state-changing routes (csrf-csrf, not csurf).
Auth-code + PKCE; state; exact redirect_uri; verify ID tokens (sig + iss/aud/exp).
No enumeration; single-use + expiring reset tokens; invalidate sessions on reset; recovery as strong as login.
express-session, argon2, @simplewebauthn, openid-client, or a managed provider. Your job is correct assembly and sound decisions — not novel cryptography. Understanding ≠ a mandate to DIY.Q1. A startup says "we'll use JWTs for everything because they're modern." Walk them through the decision instead.
"Modern" isn't a requirement. Ask: who are the clients? A single web app → session cookies are simpler and instantly revocable (L1–2). Mobile/SPA/public API → then yes, short access + rotating refresh tokens (L3, L7), with reuse detection. JWTs for browser login is the classic over-reach (L1, L3). The format follows from the client and revocation needs, not from fashion. (§01.)
Q2. In the capstone app, why call req.session.regenerate() on login rather than just setting userId on the existing session?
Session fixation defense (L2). If an attacker planted a known session id before login, reusing it would let them ride the now-authenticated session. Regenerating issues a fresh id at the moment of privilege elevation, so any pre-login id the attacker knew is useless. (§04.)
Q3. You understand every auth primitive now. Why is hand-rolling your own WebAuthn verification or password hashing still a bad idea?
Because correct assembly ≠ reimplementing crypto. The byte-level details (constant-time comparisons, CBOR parsing, signature-counter checks, parameter tuning) are where subtle bugs become vulnerabilities, and vetted libraries have already paid that cost and been audited. Your understanding lets you choose and wire them correctly and debug them — that's the leverage, not DIY crypto. (§05 warning.)
Look back at the mission: a durable mental model of modern auth + the ability to wire it into a real app. You have both. You can place any auth system on the spine, name the purpose of every parameter in a "Sign in with Google" redirect, choose a stack for a given app, and read/modify a working Express implementation. The fog is gone.
We mastered authentication. Next axis: permissions — RBAC/ABAC, scopes, policy engines. The "what may you do" half of Lesson 1.
SAML, SCIM provisioning, "Sign in with Okta" — what B2B customers demand.
OAuth client-credentials grant, API keys, service identity, mTLS, DPoP-bound tokens.
💬 This is your call — tell me which thread to pull. Or bring me your real app and we'll design its auth together against the framework in §01. And the standing offer: run the capstone (or any lab) and tell me what you saw — I'll record your first learning record and we'll build the next phase from there. · Back to Lesson 11 · Lesson 1 · Resources.