Authentication using NexAuth in NextJS
Authentication in NextJS has been made very simple by the next-auth
library, in this post we will go through on how to setup authentication in your NextJS 14 application. We will not be using NextJS 15 because it is not stable yet.
I will not go through the installation steps of Next project, we will start by installing next-auth library
npm i next-auth
Once this is done, we have to create a .env.local
file in the project root to store our variables
NEXTAUTH_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NEXTAUTH_URL="http://localhost:3000"
GITHUB_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GITHUB_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GOOGLE_CLIENT_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GOOGLE_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Here, the NEXTAUTH_SECRET
can be anything, it is used for encryption, the NEXTAUTH_URL
is used to redirect the user after the user is signed in. The GITHUB_ID
, GITHUB_SECRET
, GOOGLE_CLIENT_ID
and GOOGLE_CLIENT_SECRET
are the credentials that are to be obtained from those particular websites.
Note: While setting the credentials in Github, Google and other such auth providers, we have to set the callback url to http://localhost:3000/api/auth/callback/google
, here the http://localhost:3000
is to be replaced with your domain and the callback/google
is to be replaced with your provider name such as github
, twitter
, etc.
After this, we have to make a file with the path /lib/authOptions.ts
, it will be used to export the auth options that we are using in the app
import { NextAuthOptions } from "next-auth";
import GithubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";
export const authOptions : NextAuthOptions = {
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID as string,
clientSecret: process.env.GITHUB_SECRET as string,
}),
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
],
}
Here, we are importing the values from our .env.local
file that we made earlier.
Moving forward, we need to make one more such file in the path /src/app/api/auth/[…nextauth]/route.ts
which will be used for our client side authentication
import NextAuth from "next-auth";
import { authOptions } from "../../../../../lib/authOptions";
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
In this file, we are importing the authOptions that we exported.
Moving forward, we need to make a SessionWrapper component which will be used to as a provider in our frontend, due to this component we can use the hooks provided by NextAuth anywhere in our application.
This is the component that I created in the path, /components/SessionWrapper.tsx
, the path does not matter, but it should be a tsx or jsx component.
"use client";
import { SessionProvider } from 'next-auth/react';
import React from 'react'
function SessionWrapper({children} : {children: React.ReactNode}) {
return (
<SessionProvider>
{children}
</SessionProvider>
)
}
export default SessionWrapper
Now we have to use this wrapper in our layout.tsx file in /src/app/layout.tsx
...
return (
<SessionWrapper>
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
</SessionWrapper>
);
...
Now, we are good to use the authentication anywhere in our app, let us see how it is done.
We are provided with a useSession()
hook by next-auth which can be used to get a session variable
const {data: session} = useSession();
This variable returns false if the user is not signed in, and it contains the user data if the user is logged in.
So we can use this information to build an interface
if (session) {
return (
<>
<p>You are logged in as</p>
<p>{session.user?.name}</p>
<p>{session.user?.email}</p>
</>
);
}
return (
<>
<p> You are not logged in please, login</p>
</>
);
But, you may ask how do I sign-in and sign-out? NextAuth provides very simple functions for that as well, we just have to import them and use in our app
import { signIn } from 'next-auth/react';
...
return(
<>
<p>You are not logged in please, login</p?>
<br />
<p onClick={() => signIn("github")}>Github</p>
<br />
<p onClick={() => signIn("google")}>Google</p>
</>
);
The signOut
method is also provided which can be used directly.
Now, we are done with the basics of frontend auth, now for the backend side authentication.
This is an example of an api route which returns the user information.
import { getServerSession } from "next-auth";
import { NextRequest, NextResponse } from "next/server";
import { authOptions } from "../../../../lib/authOptions";
const GET = async (request: NextRequest) => {
const session = await getServerSession(authOptions);
if(!session){
return NextResponse.json({
"failed": "No session found"
})
}
return NextResponse.json(session);
}
export {GET};
The response is something like this:
{
"user": {
"name": "Yash",
"email": "hi@yassh.in",
"image": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.url.com"
}
}
This is enough to get you started with authentication in NextJS 14 using NextAuth library.
Subscribe to my newsletter
Read articles from Yash directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by