Next.js Authentication & Authorization Cheat Sheet

Authentication Patterns

NextAuth.js (Recommended)

// app/api/auth/[...nextauth]/route.js
import NextAuth from "next-auth";
import GitHubProvider from "next-auth/providers/github";

export const authOptions = {
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
  ],
  // ...callbacks, pages, etc.
};

export default NextAuth(authOptions);

Using Session in Server Components

// app/page.js
import { getServerSession } from "next-auth";
import { authOptions } from "./api/auth/[...nextauth]/route";

export default async function Page() {
  const session = await getServerSession(authOptions);
  return <div>{session ? `Hello, ${session.user.name}` : "Not signed in"}</div>;
}

Using Session in Client Components

'use client';
import { useSession, signIn, signOut } from "next-auth/react";

export default function AuthButton() {
  const { data: session } = useSession();
  if (session) {
    return <button onClick={() => signOut()}>Sign out</button>;
  }
  return <button onClick={() => signIn()}>Sign in</button>;
}

Protecting Routes

Middleware for Route Protection

// middleware.js
import { NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";

export async function middleware(req) {
  const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
  if (!token) {
    return NextResponse.redirect(new URL("/api/auth/signin", req.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*"], // Protect /dashboard routes
};

Server Component Guard

// app/dashboard/page.js
import { getServerSession } from "next-auth";
import { redirect } from "next/navigation";
import { authOptions } from "../api/auth/[...nextauth]/route";

export default async function Dashboard() {
  const session = await getServerSession(authOptions);
  if (!session) redirect("/api/auth/signin");
  return <div>Welcome to your dashboard, {session.user.name}!</div>;
}

Authorization (Role-Based Access)

// app/admin/page.js
import { getServerSession } from "next-auth";
import { redirect } from "next/navigation";
import { authOptions } from "../api/auth/[...nextauth]/route";

export default async function AdminPage() {
  const session = await getServerSession(authOptions);
  if (!session || session.user.role !== "admin") redirect("/");
  return <div>Admin Panel</div>;
}

Best Practices

  • Use environment variables for secrets.
  • Always check session on the server for sensitive data.
  • Use middleware for route protection and redirects.
  • Store minimal user info in the session.
  • Use HTTPS in production.