Next.js Authentication (NextAuth.js)

Implementing secure user authentication from scratch is hard. You have to handle cookies, JWTs, OAuth configurations, database sessions, and CSRF protection.

In the Next.js ecosystem, the gold standard for handling authentication is NextAuth.js (recently rebranded as Auth.js). It safely handles all these complex mechanics out of the box with zero boilerplate configuration.

Installing NextAuth

Begin by installing the library into your project:

npm install next-auth

Configuring the API Route

NextAuth takes over a single "catch-all" API route to handle login, callback, logout, and session commands all simultaneously.

In the App Router, create a file at app/api/auth/[...nextauth]/route.js.

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

export const authOptions = {
  // Configure one or more authentication providers
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    // You can also add GoogleProvider, CredentialsProvider, etc!
  ],
  secret: process.env.NEXTAUTH_SECRET,
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };

Client-Side Authentication

To know if a user is logged in on the client (browser), you wrap your application in a SessionProviderand then use the useSession hook.

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

export default function LoginStatus() {
  const { data: session, status } = useSession();

  if (status === "loading") {
    return <p>Loading...</p>;
  }

  if (session) {
    return (
      <div>
        <p>Signed in as {session.user.email}</p>
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    );
  }

  return (
    <div>
      <p>Not signed in</p>
      <button onClick={() => signIn('github')}>Sign in with GitHub</button>
    </div>
  );
}

Server-Side Authentication

NextAuth is incredibly secure because you can check the session from the Server Component directly. This means you can verify authentication before any HTML or data is ever even sent to the client!

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

export default async function ProtectedDashboard() {
  const session = await getServerSession(authOptions);

  if (!session) {
    // Immediately bounce the user to login!
    redirect("/api/auth/signin");
  }

  return (
    <div>
      <h1>Super Secret Admin Dashboard</h1>
      <p>Welcome, {session.user.name}</p>
    </div>
  );
}

Conclusion

By using NextAuth, you gain enterprise-grade security for Google, Facebook, GitHub, and Email/Password users instantly. Next, let's learn how to take our completed Next.js application and put it on the public internet via Deployment.