Implementing Authentication in Next.js with NextAuth.js

Table of contents
- Step 1: Install NextAuth.js
- Step 2: Create an API Route for Authentication
- Step 3: Configure Environment Variables
- Step 4: Protect Pages Using Middleware
- Step 5: Add the Sign-In and Sign-Out Components
- Step 6: Customize the Authentication Flow (Optional)
- Benefits of Using Middleware for Authentication
- Additional Resources for NextAuth.js

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
Centralized Logic: Middleware handles authentication at the route level, simplifying server-side logic.
Performance: Only restricted pages trigger session validation.
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:
NextAuth.js Documentation - Official documentation with detailed guides and examples.
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.
Subscribe to my newsletter
Read articles from Strnge directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Strnge
Strnge
Full-stack developer with a passion for building scalable web applications using Next.js, TypeScript, and modern technologies. Experienced in ServiceNow development and scripting. Sharing knowledge and insights on web development and programming.