Authentication is deceptively complex. Here's what I've learned building auth systems for multiple production applications.
JWT vs Sessions
**JWTs** are great for distributed systems and mobile apps. They're stateless — the server doesn't need to store session data. But they come with tradeoffs: revocation is hard, and token size can be significant.
**Session-based auth** is simpler to implement securely. The server stores a session ID, and the client sends it as a cookie. Revocation is instant — just delete the session.
Refresh Token Rotation
The pattern I recommend: 1. Access token (short-lived, 15 min) 2. Refresh token (longer-lived, 7 days, stored in httpOnly cookie) 3. Rotate refresh token on each use 4. Invalidate old refresh token immediately
OAuth2 Best Practices
- Always validate `state` parameter to prevent CSRF
- Use PKCE for public clients (SPAs, mobile apps)
- Store tokens server-side, never in localStorage
Security isn't a feature — it's a mindset.