Phase 4 · Authentication & SecurityModule 26~66 min read

Password Authentication & Sessions

Build registration and login with password hashing, constant-time verification, server-side sessions, secure cookies, and rotation.

What you'll learn

Password login combines slow password derivation, enumeration-resistant responses, an opaque server-side session, and a hardened cookie. Build the lifecycle as one security boundary.

By the end of this lesson, you'll be able to:

  • Hash passwords with async scrypt and random salts
  • Verify without timing leaks
  • Issue and rotate opaque sessions
  • Harden cookies and logout

Core mental model

Node.js becomes easier when you separate the JavaScript language from the runtime and the operating-system capabilities it exposes. Use this table as a decision guide.

ConceptWhat it meansDecision rule
Password KDFA deliberately expensive one-way derivationUse a reviewed async KDF and tune its cost
Session IDA random bearer credential referencing server stateStore only an opaque high-entropy value in the cookie
RotationReplacing a credential after privilege changeRegenerate on login, elevation, reset, and suspected compromise

Professional workflow

Build and verify Node.js programs from the terminal in small, observable steps.

  1. Define the session authentication boundary: inputs, outputs, invariants, ownership, and expected failures.
  2. Design the data or message contract before choosing implementation details.
  3. Implement the smallest correct path with dependencies passed explicitly.
  4. Add validation, failure translation, cleanup, and concurrency behavior.
  5. Verify the boundary with realistic data and at least one adversarial case.
  6. Measure or observe the behavior before optimizing or extracting abstractions.

Keep the feedback loop short

Run the smallest useful command after every meaningful change. Read the complete error message before editing again, and keep inputs and outputs visible while you learn.

Guided code lab

Derive a password hash asynchronously

A random 16-byte salt defeats precomputation; timingSafeEqual protects the comparison after lengths match.

passwords.js
import { randomBytes, scrypt as callbackScrypt, timingSafeEqual } from 'node:crypto';
import { promisify } from 'node:util';
const scrypt = promisify(callbackScrypt);

export async function hashPassword(password) {
  const salt = randomBytes(16);
  const hash = await scrypt(password, salt, 64);
  return { salt: salt.toString('base64'), hash: hash.toString('base64') };
}

export async function verifyPassword(password, record) {
  const expected = Buffer.from(record.hash, 'base64');
  const actual = await scrypt(password, Buffer.from(record.salt, 'base64'), expected.length);
  return timingSafeEqual(expected, actual);
}

Production practice

Contract

Login returns one generic failure, rotates the session on success, and sets Secure, HttpOnly, SameSite, Path, and expiry explicitly.

Verification

Test valid/invalid users with indistinguishable responses, session fixation, cookie flags, expiry, logout, and password-change revocation.

Operations

Rate-limit by account and network, tune KDF cost, encrypt session storage, and expose revocation and suspicious-login events.

Common failure mode

Fast hashes such as SHA-256 are designed for throughput and make password guessing cheap. Password storage needs a slow password KDF.

Independent workshop

Add registration, login, current-session, and logout endpoints.

Your finished workshop must include:

  • Validated credentials
  • Async password KDF
  • Generic login failure
  • Server-side session store
  • Hardened cookie
  • Rotation/revocation tests

Definition of done

Run the happy path and at least two edge cases, keep responsibilities separated, and add a short README explaining how to run the program.

Recap & quick check

Key takeaways

  • Passwords use slow KDFs
  • Salts are random per password
  • Sessions are bearer credentials
  • Cookies need explicit flags
  • Privilege changes rotate sessions

Quick check

1. Why use a password KDF?

2. What belongs in the cookie?

3. When regenerate a session?

Next: JWTs, Access Tokens & Refresh Rotation