βΆJWT vs sessions β when should I use stateless tokens instead of server-side sessions?
Sessions: server stores user state (Redis/DB), sends encrypted cookie to client. Pros: can revoke instantly, easy logout. Cons: doesn't scale β requires sticky sessions or shared state. JWT: client stores signed token, server validates signature only (no lookup). Pros: stateless, scales horizontally, good for mobile/SPA. Cons: can't revoke instantly (token lives until expiration). Best practice: Use JWT for APIs + SPAs with short expiry (15 min) + refresh tokens. Use sessions for monolithic web apps where sticky sessions OK.
βΆWhat's the difference between HS256 and RS256, and which should I use?
HS256 (HMAC): symmetric β same secret signs and verifies. Pros: fast, simple. Cons: secret must be shared across all services (risky). RS256 (RSA): asymmetric β private key signs, public key verifies. Pros: public key can be shared safely, microservices don't need the secret. Cons: slower (RSA overhead). Rule: single monolith + co-located services = HS256 OK. Microservices / multi-tenant = RS256 mandatory. ES256 (ECDSA) is newer, faster than RS256, same benefits.
βΆHow do I implement refresh tokens to avoid long-lived JWTs?
Issue two tokens: (1) Short-lived access token (15 min, high risk), (2) Longer-lived refresh token (7 days, stored in httpOnly cookie). Flow: User logs in β server issues both tokens β client uses access token for requests β token expires β client sends refresh token β server validates + issues new access token. Never put refresh token in localStorage (XSS risk). Refresh tokens can be blacklisted in DB if early logout needed. Rotate refresh tokens: issue new refresh token with each refresh (old one invalidated).
βΆWhere should I store JWT tokens in the browser β localStorage, sessionStorage, or cookies?
localStorage: XSS vulnerable (JS can steal it), but survives page reload. sessionStorage: same XSS risk, clears on tab close. Cookies: can be httpOnly (JS-proof, only sent over HTTP), but must mitigate CSRF. Best practice: httpOnly, secure, sameSite=Strict cookie for refresh token (longer-lived). Access token: either httpOnly cookie (safest) or localStorage (acceptable if SPA uses CSP). Never put JWT in regular (non-httpOnly) cookies unless you want XSS stolen.
βΆHow do I revoke or blacklist JWT tokens before expiration?
JWTs are stateless β can't revoke instantly without a server check. Options: (1) Token blacklist (Redis set of revoked jti claims, checked on every request β defeats stateless purpose). (2) Short expiry + force refresh (15 min access token + refresh rotation). (3) Logout endpoint updates user's 'token_version' field in DB, client checks version on decode. (4) JWTs with low jti counter, increment on logout (stateless revocation). Most practical: short expiry + refresh rotation. Blacklist only for high-security (logout from all devices immediately).
βΆWhat claims should I include in JWT payload, and what should I never put there?
Always include: sub (subject/user ID), iss (issuer), aud (audience/service), exp (expiration), iat (issued at). Include: roles, permissions, org_id. Never include: passwords, credit cards, PII like SSN/address. Remember: JWT payload is base64-encoded (not encrypted) β anyone can read it. Use JWE (JSON Web Encryption) if payload must be private. Keep payload small (sent with every request). If payload > 1KB, use opaque token + server lookup instead.
βΆWhat are the common JWT security vulnerabilities, and how do I avoid them?
Critical: (1) 'none' algorithm β always reject alg=none. (2) Weak signing key β use strong secrets (32+ chars) for HS256, proper RSA for RS256. (3) Not validating exp β check expiration every decode. (4) Trusting unverified tokens β always verify signature server-side. (5) Storing in localStorage β use httpOnly cookies. (6) Algorithm confusion β specify expected algorithm when verifying (don't trust client's alg claim). (7) JWKS endpoint not cached β cache public keys with a 1-hour TTL to avoid lookups on every request.