Authentication answers a single question: is this request really from the person it claims to be? Get it wrong and nothing else in your security model matters. Get it right and most of your users will never notice it exists.
← Back to Security
// Node — argon2id
import argon2 from 'argon2';
const hash = await argon2.hash(password, { type: argon2.argon2id });
const valid = await argon2.verify(storedHash, password);
| Factor | Strength | Notes |
|---|---|---|
| SMS code | Weak | Vulnerable to SIM swap. Better than nothing — barely. |
| TOTP (authenticator apps) | Strong | Phishable but solid baseline. Free, no hardware. |
| Push notification | Strong | UX-friendly; "MFA fatigue" attacks are real — require number-matching. |
| WebAuthn / Passkey | Strongest | Phishing-resistant. The future. See passkeys deep dive → |
| Hardware token (YubiKey) | Strongest | WebAuthn implementation in physical form. |
If you ship one auth feature this quarter, ship MFA. MFA deep dive →
Login creates a server record; the browser holds a random opaque session ID in an HttpOnly Secure SameSite cookie. Every request looks up the session.
Pros: easy invalidation (delete the row), small cookie, no leaking claims to the client. Cons: requires sticky sessions or shared session store (Redis).
Default for traditional web apps. Boring in the good way.
Login mints a signed token containing claims (user ID, roles, expiry). Server verifies the signature on each request — no DB lookup.
Pros: stateless, easy across services. Cons: can't be revoked before expiry without an extra denylist; claims are world-readable; choosing the wrong algorithm or library has burned many teams.
Use short expiries (5–15 min) plus a refresh token. Never put sensitive data in the payload — it's signed, not encrypted. JWT deep dive →
HttpOnly — JS can't read it (XSS mitigation).Secure — only sent over HTTPS.SameSite=Lax (or Strict) — CSRF mitigation. CSRF deep dive →__Host- prefix — locks the cookie to its origin.For most apps, the right answer is delegate. Use OIDC against Google/Microsoft/Apple, or a managed provider (Auth0, Clerk, Cognito, Authentik), and inherit decades of someone else's hard-won security work.
alg: none / algorithm confusion. Pin the algorithm server-side.See also: Broken Authentication (OWASP) →
argon2.verify(row.password_hash, password) — constant-time.HttpOnly Secure SameSite=Lax cookies, prefixed __Host-.