Authentication & Security
Secure authentication systems: password hashing, sessions, JWT, OAuth, and common vulnerabilities to avoid.
Authentication is Hard
Getting authentication wrong = compromised user data. Getting it right is non-negotiable for any production app.
This guide covers what you MUST do to secure user accounts.
Password Hashing
Never Store Plain Text Passwords
Use bcrypt. It's slow (by design) which makes password cracking infeasible.
Bcrypt Implementation
- Hash password with bcrypt on signup
- Store hash in database
- On login, hash submitted password and compare to stored hash
- Use salt rounds of 12 (default)
Never Use
- MD5 (broken)
- SHA1 (broken)
- Custom algorithms
- Salts less than 128 bits
Session Management
HTTP-Only Cookies
Store session tokens in HTTP-only cookies. Browser automatically includes them in requests.
Protects against XSS attacks. JavaScript can't access HTTP-only cookies.
Session Expiry
Sessions should expire after 1-8 hours. Offer "remember me" with longer expiry (1-30 days).
Refresh Tokens
Use short-lived access tokens (15 min) and long-lived refresh tokens (7 days). Exchange refresh token for new access token.
JWT (JSON Web Tokens)
Structure
JWT has three parts: header, payload, signature. Server signs the token. Browser stores it.
Verification
On every request, verify the JWT signature. If signature is invalid, reject the request.
Payload
Include user ID, email, and roles. Don't include sensitive data (passwords, API keys). Payload is not encrypted, only signed.
OAuth (Social Login)
How it Works
User clicks "Sign in with Google". Redirected to Google. User approves. Google redirects back with auth code. Exchange code for user info.
Never Store OAuth Tokens
You don't need to store the OAuth access token. Just use it once to get the user's email/profile. Create your own session.
Email Verification
If using email/password auth, send verification emails. Don't let unverified emails access sensitive features.
Common Vulnerabilities
CSRF (Cross-Site Request Forgery)
Include a CSRF token in forms. Verify on submission. Frameworks like Next.js handle this automatically.
SQL Injection
Always use parameterized queries. Never concatenate user input into SQL.
XSS (Cross-Site Scripting)
Sanitize user input. Escape output. Use Content Security Policy headers.
Weak Passwords
Enforce strong password requirements: 12+ characters, mix of cases, numbers, special chars.
Security Headers
Must-Have Headers
- Content-Security-Policy: Prevents XSS
- X-Frame-Options: Prevents clickjacking
- X-Content-Type-Options: Prevents MIME sniffing
- Strict-Transport-Security: Forces HTTPS
Build Securely
Start with bcrypt + HTTP-only cookies. Add OAuth if needed. Monitor logs for suspicious activity. Rotate secrets regularly.
Key Takeaways
- •Practical tools and techniques you can implement today
- •Real-world examples from production systems
- •Common mistakes to avoid and how to fix them
Related Guides
Want more articles like this?
Subscribe to get practical guides and case studies delivered to your inbox. No spam, just real systems that work.