Authentication
Login, signup, sessions, OAuth OAuth A secure way to log in using another account (like Google or GitHub) without sharing your password with the app. "Like a hotel key card. The front desk (Google) vouches for you, so the room (app) lets you in."
Why Authentication Matters
Authentication answers the question: "Who are you?" Without it, anyone can access any data. With it, you can personalize experiences, protect sensitive info, and build real products.
User Accounts
Save preferences, data
Protected Routes
Dashboard, admin, API
Billing & Payments
Subscriptions, purchases
Your Options
ClerkRECOMMENDED
The easiest auth for modern apps
Best For
- • Next.js apps (first-class support)
- • Quick setup (<10 min)
- • Beautiful pre-built UI components
- • Social login (Google, GitHub, etc.)
Considerations
- • Paid after 10k monthly users
- • Hosted solution (not self-hosted)
- • User data lives on Clerk servers
# Install
npm install @clerk/nextjs
NextAuth.js (Auth.js)FLEXIBLE
Open-source, self-controlled auth
Best For
- • Full control over auth flow
- • Custom database storage
- • Enterprise/compliance needs
- • No vendor lock-in
Considerations
- • More setup required
- • Need to build your own UI
- • Database adapter configuration
# Install
npm install next-auth
Supabase AuthFULL STACK
Auth bundled with your database
Best For
- • Already using Supabase for DB
- • Row Level Security (RLS)
- • Real-time subscriptions + auth
- • PostgreSQL lovers
Considerations
- • Tied to Supabase ecosystem
- • UI components less polished
- • Learning curve for RLS
# Install
npm install @supabase/supabase-js @supabase/ssr
Auth0 / Firebase Auth
Enterprise-grade solutions
Best For
- • Enterprise SSO requirements
- • Complex identity needs
- • Mobile apps (Firebase)
- • Multi-tenant applications
Considerations
- • More complex than needed for small apps
- • Auth0 gets expensive at scale
- • Firebase: Google lock-in
Quick Decision Guide
| If you want... | Use |
|---|---|
| Fastest setup, beautiful UI out of the box | Clerk |
| Full control, own your data, free forever | NextAuth.js |
| Already using Supabase database | Supabase Auth |
| React Native / Flutter mobile app | Firebase Auth |
| Enterprise SSO (Okta, SAML, etc.) | Auth0 or Clerk |
Authentication Methods
Email + Password
Traditional signup. User creates account with email and password.
Best for: Any app, universal
Magic Link
Passwordless. User enters email, gets a login link.
Best for: Low-friction signup, newsletters
Social OAuth
"Sign in with Google/GitHub". One-click login.
Best for: Developer tools, consumer apps
Passkeys / WebAuthn
Biometric login. Face ID, fingerprint, hardware keys.
Best for: High-security apps, future-proofing
Common Pitfalls
The OAuth Trap
Vibe-coded your app and hit "redirect_uri_mismatch"? You're not alone. Deep dive into the 5-part OAuth setup.
OAuth Providers Deep Dive
Google, GitHub, Apple, X, Facebook, Microsoft, and more. Pros, cons, costs, and setup for each provider.
"I'll build auth myself"
DIY auth is a security minefield. Password hashing, session management, CSRF protection, rate limiting...
Fix: Use a battle-tested auth library. The time saved and security gained is worth it.
"Storing passwords in plain text"
If your database leaks, every password is exposed.
Fix: Always hash passwords with bcrypt or Argon2. Auth libraries handle this automatically.
"Exposing user IDs in URLs"
/user/123 lets attackers enumerate users by changing the ID.
Fix: Use UUIDs instead of sequential IDs, or always verify the requesting user owns the resource.
"No email verification"
Anyone can sign up with fake@email.com and you can't contact them.
Fix: Enable email verification in your auth provider. Most have it built in.
"Tokens in localStorage"
localStorage is accessible via JavaScript = vulnerable to XSS attacks.
Fix: Use httpOnly cookies for session tokens. Auth libraries handle this correctly.
Quick Setup: Clerk + Next.js
Create Clerk account & get keys
Go to clerk.com, create an app, copy your API keys.
Add to .env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
Install & wrap your app
// app/layout.tsx
import { ClerkProvider } from '@clerk/nextjs'
export default function RootLayout({ children }) {
return (
<ClerkProvider>
{children}
</ClerkProvider>
)
}
Add sign in / user button
import { SignInButton, UserButton } from '@clerk/nextjs'
// In your navbar
<SignInButton />
<UserButton />
Protect routes with middleware
// middleware.ts (root of project)
import { clerkMiddleware } from '@clerk/nextjs/server'
export default clerkMiddleware()
export const config = {
matcher: ['/((?!.*\\..*|_next).*', '/', '/(api|trpc)(.*)']
}
That's it!
You now have login, signup, social auth, user profiles, and protected routes. Clerk handles everything else.