Authentication and Authorisation: Passwords, JWT, and OAuth
Auth is tested in every security exam and interview. Here's the concepts you need — from password hashing to OAuth flows.
Authentication vs authorisation
Authentication verifies WHO you are. Authorisation determines WHAT you can do.
# Authentication: "who are you?" # - Password + username # - Certificate # - Biometric # - Multi-factor (MFA) # Authorisation: "what can you do?" # - Role-Based Access Control (RBAC): permissions via roles # - Attribute-Based Access Control (ABAC): permissions via attributes # - Access Control Lists (ACL): per-resource permission lists # Example flow: # 1. User sends username + password (authentication) # 2. Server verifies credentials, issues JWT token # 3. User sends token with each request # 4. Server verifies token and checks permissions (authorisation)
Password hashing
Never store plaintext passwords. Use a purpose-built hashing algorithm with salting.
# WRONG: store plaintext password users[email] = password # never do this # WRONG: use MD5 or SHA-256 import hashlib hashlib.md5(password.encode()).hexdigest() # crackable with rainbow tables # CORRECT: use bcrypt, scrypt, or Argon2 import bcrypt # Storing password: salt = bcrypt.gensalt() hashed = bcrypt.hashpw(password.encode(), salt) store_in_db(hashed) # Verifying password: bcrypt.checkpw(provided_password.encode(), stored_hash) # Why bcrypt is good: # - Incorporates salt automatically (prevents rainbow table attacks) # - Configurable work factor (slow by design) # - Resistant to brute force
JSON Web Tokens (JWT)
JWTs are a common stateless authentication mechanism. They carry claims that are cryptographically signed.
# JWT structure: header.payload.signature
# Each part is Base64URL encoded
# Header: algorithm and token type
{ "alg": "HS256", "typ": "JWT" }
# Payload: claims (not encrypted, only signed!)
{
"sub": "user123",
"email": "[email protected]",
"role": "admin",
"iat": 1713523200, # issued at
"exp": 1713609600 # expires
}
# Signature: HMACSHA256(base64(header) + "." + base64(payload), secret)
# Key facts:
# - Payload is readable by anyone (base64 decoded) — don't put secrets here
# - Signature verification ensures the token wasn't tampered with
# - Server validates signature without database lookup (stateless)
# - Store in httpOnly cookie (not localStorage — XSS risk)OAuth 2.0 flows
OAuth 2.0 is an authorisation framework that lets applications access resources on behalf of users.
# OAuth 2.0 grant types: # Authorization Code (most common, most secure) # 1. App redirects user to auth server # 2. User logs in, approves scopes # 3. Auth server redirects back with code # 4. App exchanges code for access + refresh tokens # Use: web apps, mobile apps # Client Credentials # 1. App sends client_id + client_secret # 2. Gets access token # 3. No user involved # Use: machine-to-machine (service accounts) # PKCE (Proof Key for Code Exchange) # Authorization Code flow + a code_verifier/code_challenge # Prevents auth code interception attacks # Required for public clients (SPAs, mobile apps) # Key terms: # Access token: short-lived (15 min - 1 hr), used for API calls # Refresh token: long-lived, used to get new access tokens
Exam tip
Know three things cold: (1) bcrypt for passwords, not MD5/SHA-256. (2) JWT payloads are base64-encoded but NOT encrypted — never put secrets in them. (3) Store JWTs in httpOnly cookies, not localStorage.
Think you're ready? Prove it.
Take the free Cybersecurity readiness test. Get a score, topic breakdown, and your exact weak areas.
Take the free Cybersecurity test →Free · No sign-up · Instant results