Implementing Authentication in Next.js with NextAuth.js

Implementing Authentication in Next.js with NextAuth.js

·

3 min read

NextAuth.js is a popular authentication library for Next.js that simplifies the process of implementing user authentication. It provides a robust and customizable solution for handling different authentication methods, including credentials, OAuth providers, and more. This guide walks you through setting up a basic authentication system in a Next.js application using NextAuth.js.


Step 1: Install NextAuth.js

First, install NextAuth.js and the necessary dependencies:

npm install next-auth @next-auth/prisma-adapter

If you plan to use a database, make sure you have an ORM like Prisma or an appropriate adapter installed.


Step 2: Create an API Route for Authentication

NextAuth.js requires an API route to handle authentication requests. Create a new file src/pages/api/auth/[...nextauth].ts:

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.GitHub({
      clientId: process.env.GITHUB_CLIENT_ID,
      clientSecret: process.env.GITHUB_CLIENT_SECRET,
    }),
    // Add more providers as needed
  ],
  callbacks: {
    async session({ session, user }) {
      session.user.id = user.id;
      return session;
    },
  },
  secret: process.env.NEXTAUTH_SECRET,
});

This configuration uses GitHub as an OAuth provider. Replace GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET with your GitHub app credentials. You can add other providers as needed.


Step 3: Configure Environment Variables

Add the required environment variables in a .env.local file at the root of your project:

GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your_secret_key

Replace your_github_client_id, your_github_client_secret, and your_secret_key with appropriate values.


Step 4: Protect Pages Using Middleware

Instead of using getServerSession, we can use middleware to protect routes and handle redirections. Create a middleware file in src/middleware.ts:

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 });
  const { pathname } = req.nextUrl;

  // Allow access to public paths
  if (pathname.startsWith('/api/auth') || pathname === '/signin') {
    return NextResponse.next();
  }

  // Redirect if no token is found
  if (!token) {
    return NextResponse.redirect(new URL('/signin', req.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: [
    '/protected/:path*', // Protect paths that start with /protected
  ],
};

This middleware checks for a valid session token and redirects unauthenticated users to the sign-in page.


Step 5: Add the Sign-In and Sign-Out Components

To allow users to sign in and out, create a simple component using NextAuth.js hooks:

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

export default function AuthButton() {
  const { data: session } = useSession();

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

  return <button onClick={() => signIn()}>Sign In</button>;
}

Step 6: Customize the Authentication Flow (Optional)

You can customize the authentication flow by modifying the pages property in the NextAuth.js configuration:

export default NextAuth({
  pages: {
    signIn: '/auth/signin',
    signOut: '/auth/signout',
    error: '/auth/error',
    verifyRequest: '/auth/verify-request',
    newUser: '/auth/new-user',
  },
});

Create the corresponding pages in the src/pages/auth directory to match the paths defined above.


Benefits of Using Middleware for Authentication

  1. Centralized Logic: Middleware handles authentication at the route level, simplifying server-side logic.

  2. Performance: Only restricted pages trigger session validation.

  3. Flexibility: Easily configure protected and public routes.


Additional Resources for NextAuth.js

To dive deeper into NextAuth.js and related topics, explore the following resources:

  1. NextAuth.js Documentation - Official documentation with detailed guides and examples.

  2. Securing Next.js Applications - Learn more about authentication strategies in Next.js.

These links provide additional insights and examples to help you expand your knowledge and make the most of NextAuth.js in your projects.