BiTree
  • Search For Lessons
  • Curriculum
  • Pricing
  • For Educators
  • Become a Tutor
  • About
  • Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
BiTree

Live coding lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Search For Lessons
  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Become a Tutor
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 BiTree. All rights reserved.
Curriculum/Web Development/Security for Developers/Secure Authentication Practices
50 minIntermediate

Secure Authentication Practices

After this lesson, you will be able to: Hash passwords with bcrypt or Argon2id, secure sessions with the right cookie flags, avoid the common JWT pitfalls, implement TOTP-based MFA, and harden an OAuth flow.

Authentication is where most apps get breached. This lesson covers password hashing (never plaintext; Argon2id or bcrypt), session management with HttpOnly/Secure/SameSite cookies, JWT security including the alg:none attack, MFA with TOTP, and OAuth security (state parameter, redirect URI validation).

Prerequisites:How the Web Works

Password hashing: bcrypt vs Argon2id

Never store plaintext passwords, and never use a fast hash like SHA-256 for them (attackers compute billions per second on a GPU). Use a slow, salted password hash. Argon2id is the current recommendation (memory-hard, resists GPU and ASIC attacks); bcrypt is still acceptable and widely supported. Both salt automatically. The 'cost' parameter (bcrypt rounds, Argon2 memory/iterations) is tuned so a single hash takes a fraction of a second on your server, making mass cracking infeasible. Re-calibrate cost as hardware gets faster.

Hashing and verifying a password

Argon2id with sensible defaults. The salt is generated and stored inside the hash string automatically.

python
import argon2 from "argon2";
// On signup / password change
const hash = await argon2.hash(plainPassword, { type: argon2.argon2id });
// store `hash` in the DB; never store the plain password
// On login
const ok = await argon2.verify(storedHash, submittedPassword);
if (!ok) {
// generic error: do not reveal whether the email or the password was wrong
return { error: "Invalid email or password" };
}

Session management and cookie flags

Session cookies must be HttpOnly (JavaScript cannot read them, blocking XSS theft), Secure (sent only over HTTPS), and SameSite (Strict or Lax to blunt CSRF; None requires Secure and is only for genuine cross-site needs). On logout, invalidate the session server-side (delete the session record), not just the cookie, otherwise a stolen cookie still works. Rotate the session identifier on login to prevent session fixation, where an attacker plants a known session ID before the victim authenticates.

JWT security and the alg:none attack

A JSON Web Token is signed data the server can verify without a database lookup. The classic vulnerability is alg:none: an attacker changes the header's algorithm to 'none' and removes the signature; a naive library accepts it. Always verify the signature with a pinned algorithm and reject 'none'. Keep access tokens short-lived and use refresh-token rotation. Do not store anything sensitive in localStorage (any XSS reads it); for sessions prefer HttpOnly cookies over localStorage-held JWTs.

MFA with TOTP, and OAuth security

TOTP (the codes in Google Authenticator/Authy) works from a shared secret and the current time, hashed into a 6-digit code valid for a 30-second window. The server stores the shared secret once at enrollment and verifies codes against it. SMS is a weak second factor (SIM swapping, interception); prefer TOTP or hardware keys (FIDO2/WebAuthn). Always issue recovery codes and store them hashed. For OAuth, use the state parameter to prevent CSRF on the callback, strictly validate the redirect URI against an allowlist, and avoid the deprecated implicit flow in favor of authorization code with PKCE.

Quick Check

Why must a session cookie be HttpOnly?

Pick the best reason.

Common mistakes only experienced devs catch

Using SHA-256 or MD5 for passwords instead of a slow salted hash. Revealing whether the email or the password was wrong (lets attackers enumerate accounts; return one generic error). Storing JWTs in localStorage where XSS can steal them. Accepting alg:none or letting the client pick the algorithm. Only deleting the cookie on logout while the server-side session stays valid. Treating SMS as strong MFA. Skipping the OAuth state parameter, leaving the callback open to CSRF.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←HTTP Security Headers
Back to Security for Developers
Dependency Security and Supply Chain→