AuthN vs AuthZ (lead with this)
Authentication = who are you (identity). Authorization = what may you do (permissions). 401 maps to the first, 403 to the second. Interviewers open here.
Four credential mechanisms and when each fits
- API keys — one long-lived bearer secret (
sk_...) identifying an app, not a user. Simple, good for server-to-server. No expiry, no scope, catastrophic if leaked. Send asAuthorization: Bearer, never in URLs (they land in logs). - Sessions (stateful) — server issues an opaque session id in a cookie; data lives server-side. Easy to revoke; costs a lookup per request. Cookies need
HttpOnly,Secure,SameSite. - JWT (stateless) — a self-contained signed token:
header.payload.signature, each part Base64URL. Signed, not encrypted — the payload is readable by anyone, so never put secrets in it. Claims (RFC 7519):iss,sub,aud,exp(expiry),iat,jti. Verify the signature andexp/iss/aud, and pin the expectedalgserver-side. Stateless scales but is hard to revoke before expiry → keep access-token TTLs short (5–15 min) + refresh tokens. - OAuth 2.0 — delegated authorization: let a user grant your app scoped access to their data elsewhere without sharing their password.
OAuth 2.0 authorization-code flow
- App redirects the user to the authorization server with
client_id,redirect_uri,scope,state(CSRF token), and a PKCEcode_challenge. - User authenticates and consents.