How I Integrated Authentication Next-Auth V5 in my NextJS 14 Application
How to Integrate Authentication in a Next.js Project
This comprehensive guide will walk you through the process of integrating Next Auth v5 into a Next.js project. If you prefer a video walk-through, there is also one on my channel:
I recently integrated the new version of next-auth, which is V5. The installation took longer than I expected due to the lack of documentation. Since next-auth is becoming part of auth.js, original website does contain more detailed documentation for previous versions, but the new version documentation is still in progress to be migrated to the new website. Let’s dive into all the steps I took to set it up and also explore how to use session information and auth functions both in server and client components!
Step 1: Set up your Next.js project
First, you need a Next.js project to work with. If you don’t have one yet, you can create it using the create-next-app
command in your terminal. This command will set up a new project with all the necessary files and dependencies for a Next.js application.
npx create-next-app@latest
Step 2: Install Next Auth
The next step is to install the Next Auth module. You can do this by running the following command in your terminal once you navigate to your project:
npm install next-auth@beta
This command will add Next Auth to your project’s dependencies, allowing you to use it for authentication.
Step 3: Create an Auth Config File
You will need to create a configuration file for your Next Auth setup. Navigate to your src
folder and create a new file named auth.js
(or auth.ts
if you're using TypeScript). If you don’t have a src
folder in your project than file can be created at the root of the project. In this file, we will export your Next Auth function and add the configuration for the authentication provider:
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
export const {
handlers: { GET, POST },
auth,
signIn,
signOut,
} = NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
],
});
Step 4: Configure a Provider
The Provider dictates how users can log in to your application. This could be via email, password, or using social accounts like Google or Facebook. In this case, the Google Provider is configured. And in the next steps, we will store your Google client ID and client secret as environment variables for security purposes. These are obtained when you set up your Google OAuth credentials.
Step 5: Create API Routes
Next, we need the API routes that your authentication functions will use. Inside the app
folder, create a new folder named api
. Then, inside the api
folder, create a new folder named auth
. Inside auth
, create another folder named [...nextauth]
. Inside this folder, create a new file named route
.js (or route
.ts` if you're using TypeScript). This should setup the routing for your authentication functions by following code:
// api/auth/[...nextauth]/route.ts
export { GET, POST } from "../../../../auth";
Step 6: Add Environment Variables
Next, add your Google Client ID and Google Client Secret to your .env
file. We can obtain our api keys at google cloud console. Click “Create New Project” → Find “Credentials” Button → “Create Credentials” → Select “OAuth Client ID” → and before saving add an authorized url:
http://localhost:3000/api/auth/callback/google
This is the url that will be making a request to Google. On the way it might ask you to setup the consent screen first and details like — app name and support email. This information is what will be displayed once user is asked to login using their google account. Once you save the consent screen information you can finish creating credentials and secret and client id will show up on the screen. You can add them in .env as following:
GOOGLE_CLIENT_ID= // your client id here
GOOGLE_CLIENT_SECRET= //your client secret here
Step 7: Add Auth Secret
Per their new and old documentation, this step seems to be optional but I did receive an error when I hadn’t gone through it in my project, that’s why I included in this guide. In this step, you can add another variable in your .env file:
AUTH_SECRET=
and the value you can generate by running
openssl rand -hex 32
in your terminal OR online using this link
Step 8: Test your API route
To confirm that your API route is working correctly, navigate to localhost:3000/api/auth/signin
in your browser. It should redirect you to a Google sign-in page. This means that your API route is working and your Google Provider is properly configured.
Step 9: Add Authentication in Your Server Components
Let’s say you have a header.tsx
in your page.tsx
where you want to access the user information. You can do the following:
import { auth } from '../auth'; // correct path to your auth config
export const Header = async () => {
const session = await auth();
return (
<header>
<p>Welcome {session.user.name}</p>
</header>
)
You can even add the login link and sign out button based on the session information:
import { auth, signIn, signOut } from '@/auth';
import Image from 'next/image';
import Link from 'next/link';
function SignOut() {
return (
<form
action={async () => {
'use server';
await signOut();
}}
>
<button type="submit">Sign out</button>
</form>
);
}
export const Header = async (props: Props) => {
const session = await auth();
console.log(session);
return (
<header>
<nav>
<div>
<Link href="/"><h1>Your Logo</h1></Link>
<div>
{
session?.user ? (
<div>
{
session.user.name && session.user.image &&
<Image
src={session.user.image}
alt={session.user.name}
width={32}
height={32}
/>
}
<SignOut />
</div>
) : (
<Link href="/api/auth/signin">
<button variant="link">Sign in</button>
</Link>
)
}
</div>
</div>
</nav>
</header>
)
}
Step 9: Add Authentication to your Client Components
Now, you can begin adding authentication to your components. In your components, import the useSession
hook from next-auth/react
. This hook gets updated whenever there are changes to the session (i.e., when a user logs in or out). You can use this hook to conditionally render components based on whether a user is signed in. For example:
// form.tsx
'use client'
import React, { useState, useEffect } from 'react'
import { useSession, signIn } from "next-auth/react";
const UserForm = () => {
const session = useSession();
const onSubmit = () => {
if (session.status !== "authenticated") {
signIn(); // will re-direct to sign in page
} else {
// do something else
}
return (
<form onSubmit={onSubmit}>
<input type="text" placeholder="Your name"/>
<button type="submit" />
</form>
)
};
But before you can test out session on your client components you have to do:
Step 10: Wrap your application in a Provider
The final step is to wrap your application in a SessionProvider
from next-auth/react
. This allows you to use the useSession
hook in your components. You can either wrap your entire application in this provider, or just the individual components that need access to session information.
import { SessionProvider } from "next-auth/react"
export default function App() {
<SessionProvider>
// rest of your application
</SessionProvider>
}
Congratulations! You have now integrated authentication into your Next.js project using Next Auth. Your users can now sign in to your application using their Google accounts.
After the integration, I also connected the auth to my database, it’s part of the project tutorial, which if you want to follow along can check it out here🙂