contentintech
Advanced

Authentication Cheatsheet

Quick reference for authentication — hashing recipes, cookie flags, JWT anatomy, OAuth/PKCE flow, RBAC, TOTP, and attack mitigations.

JWTOAuthHashingSessions
NotesCheatsheet

AuthN vs AuthZ

TermQuestionFail status
AuthenticationWho are you?401
AuthorizationWhat can you do?403

Password Hashing

Argon2 (recommended)

import argon2 from 'argon2';
const hash = await argon2.hash(pw, { type: argon2.argon2id });
const ok   = await argon2.verify(hash, pw);   // constant-time

bcrypt

import bcrypt from 'bcrypt';
const hash = await bcrypt.hash(pw, 12);   // cost factor 12+
const ok   = await bcrypt.compare(pw, hash);   // max 72 bytes

Rules

DoDon't
Argon2id / bcrypt / scryptMD5, SHA-1, SHA-256
Per-user random salt (auto)Plaintext or encryption
Constant-time verifyLeak which field was wrong

Cookies & Sessions

Secure Cookie

Set-Cookie: __Host-sid=abc;
  HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=28800

Cookie Flags

FlagProtects against
HttpOnlyXSS reading the cookie
SecureLeak over plain HTTP
SameSite=Lax/StrictCSRF
__Host-Cookie scope confusion
// Prevent fixation: new ID on login
req.session.regenerate(() => { req.session.userId = id; });

JWT

Anatomy

header.payload.signature   (3 base64url parts)

header    { "alg": "HS256", "typ": "JWT" }
payload   { "sub", "role", "iat", "exp" }
signature HMAC(base64url(header)+"."+base64url(payload), secret)
// base64 = encoding, NOT encryption -> no secrets in payload

Sign & Verify

import jwt from 'jsonwebtoken';
const t = jwt.sign({ sub: id, role }, SECRET, { expiresIn: '15m' });
const c = jwt.verify(t, SECRET, { algorithms: ['HS256'] }); // pin alg!
// Authorization: Bearer <token>

Access vs Refresh

AccessRefresh
Lifetime5–15 minDays–weeks
StorageMemory / headerHttpOnly cookie
RevokeWait for expiryServer-side + rotate

Sessions vs JWT

AspectSessionJWT
StateServer-sideIn token
RevokeInstantHard
ScaleShared storeStateless
Best forWeb appsAPIs / mobile

OAuth 2.0 / OIDC

Auth Code + PKCE

verifier  = random(32)
challenge = base64url(sha256(verifier))

1. GET /authorize?response_type=code&client_id=APP
     &redirect_uri=...&scope=openid%20profile&state=xyz
     &code_challenge=CHALLENGE&code_challenge_method=S256
2. -> redirect back ?code=...&state=xyz   (verify state!)
3. POST /token  grant_type=authorization_code
     &code=...&code_verifier=VERIFIER&redirect_uri=...
4. { access_token, refresh_token, id_token, expires_in }

Grants

GrantUse
Auth Code + PKCEAll user-facing apps
Client CredentialsMachine-to-machine
Refresh TokenRenew access token
Implicit / PasswordDeprecated — avoid

OAuth = authorization. OIDC adds id_token (JWT) for authentication.

RBAC & MFA

RBAC Middleware

const can = (perm) => (req, res, next) => {
  if (!req.user) return res.status(401).end();
  if (!ROLES[req.user.role]?.includes(perm))
    return res.status(403).end();
  next();
};
app.delete('/posts/:id', can('post:delete'), handler);
// + always check ownership, not just role

TOTP (RFC 6238)

import { authenticator } from 'otplib';
const secret = authenticator.generateSecret();
const uri = authenticator.keyuri(email, 'MyApp', secret); // QR
const ok  = authenticator.verify({ token, secret });

Factors

CategoryExample
KnowPassword, PIN
HaveTOTP app, passkey, hardware key
AreFingerprint, face

Attacks & Mitigations

AttackMitigation
CSRFSameSite + anti-CSRF token, check Origin
XSSOutput encoding, CSP, HttpOnly cookies
Session fixationRegenerate session ID on login
Credential stuffingRate limit, MFA, breached-pw check
Brute forceSlow hash, throttle, backoff
Token theftShort expiry, rotation, TLS
JWT alg confusionPin algorithms, reject alg:none

Section navigation