Back to Guides
GuideFeb 2, 2025

Authentication & Security

Secure authentication systems: password hashing, sessions, JWT, OAuth, and common vulnerabilities to avoid.

22 min read
Published Feb 2, 2025

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

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.