Implementing Authentication with NextAuth.js
Authentication is the part of your app you least want to hand-roll. NextAuth.js (now Auth.js) gives you OAuth providers, sessions, and CSRF protection with a few dozen lines of configuration.
Installation and Setup
added 18 packages in 4s✔ Secret written to .env.local (AUTH_SECRET)Configure your providers in one place. GitHub login for a developer-facing product is a two-minute job:
// auth.tsimport NextAuth from 'next-auth';import GitHub from 'next-auth/providers/github'; export const { handlers, auth, signIn, signOut } = NextAuth({ providers: [GitHub], session: { strategy: 'jwt' },});Protecting Pages and APIs
Server Components can check the session directly — no client-side flash of protected content:
export default async function DashboardPage() { const session = await auth(); if (!session) redirect('/login'); return <Dashboard user={session.user} />;}A Practical Security Checklist
Beyond the happy path: keep AUTH_SECRET out of the repository and rotate it on a schedule, request only the OAuth scopes you actually use, set session maxAge deliberately rather than accepting defaults, and protect API route handlers with the same auth() check as pages — attackers call endpoints directly, not through your UI.
Choose JWT sessions for stateless simplicity or database sessions when you need server-side revocation — the ability to end a specific session the moment a laptop is reported stolen. Either way, the boring habits are the ones that keep you out of the incident channel: least privilege, short-lived tokens, and an audit trail for sign-ins.