In this tutorial, you'll learn how to secure your Next JS application with NextAuth.js. It's a library specially built for Next JS to implement a social login authentication for your apps. NextAuth.js supports out-of-the-box a long list of providers like Apple, Auth0, Amazon Cognito, Facebook, GitHub, Google, Twitter, etc. The good news you can add it to your current or new NextJS project in 5 minutes.
This guide will focus on the GitHub OAuth login for your React application. But, you can easily use another social identity provider by changing some variables.
You need to install the following dependencies to your Next JS app:
npm install next-auth
npm install @types/node @types/react typescript @types/next-auth --save-dev # Optional TypeScript Support
If you don't have a Next JS application, you can use npx create-next-app
to create an app from scratch.
Create a file in pages/api/auth
named [...nextauth].ts
:
import { NextApiRequest, NextApiResponse } from "next";
import NextAuth, { InitOptions } from "next-auth";
import Providers from "next-auth/providers";
const options: InitOptions = {
// Configure one or more authentication providers
providers: [
Providers.GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
};
export default (req: NextApiRequest, res: NextApiResponse) => NextAuth(req, res, options);
In Next Js, a filename surrounded by brackets is a dynamic route
. In our case, any routes under /api/auth
and all subfolders are handled by [...nextauth].ts
file. Inside the file, the library handles almost everything, you only need to configure and provide some information to NextAuth.js library.
As you can see in the previous code, the client id and secret aren't hardcoded, and it uses the environment variable. Handling environment variable in Next JS is extremely easy, you only require to create a file named .env.local
:
NEXTAUTH_URL=http://localhost:3000
GITHUB_ID=XXX
GITHUB_SECRET=XXX
Replace XXX
with your id and secret value. As you may notice, the filename is ended by local
. It avoids publishing this sensitive information to your git repository.
In this step, we need to implement a React button to sign in and sign out. So, in your index.tsx
or any Next JS pages, add the following code:
import React from "react";
import { signIn, signOut, useSession } from "next-auth/client";
const Index = () => {
const [session] = useSession();
return (
<>
{!session && (
<>
Not signed in <br />
<button onClick={() => signIn("github")}>Sign in</button>
</>
)}
{session && (
<>
Now you are signed in, only signed in user can see the following button
<button onClick={() => signOut()}>Sign out</button>
</>
)}
</>
);
};
export default Index;
As you can see, Next Auth JS provides us two functions: signIn
and signOut
. It also provides a React Hook useSession
to check if the user is signed in or not.
You need to add Provider
component in your _app.tsx
:
import { Provider } from "next-auth/client";
import { AppProps } from "next/app";
const App = ({ Component, pageProps }: AppProps) => {
return (
<Provider session={pageProps.session}>
<Component {...pageProps} />
</Provider>
);
};
export default App;
With the previous code, all your useSession
hooks are now sharing the same state.
In this guide, you have implemented a user authentication in Next JS. It secures some part of your application by showing only to users who have signed. This tutorial covers the most basic use case for your React application with a simple login and logout. You can go further by retrieving user information like email addresses and display them in your Next JS app.
As an alternative to Next.js Auth, you can also try Next.js Amplify Cognito a Serverless authentication provided by AWS. The perfect solution to implement auth in a Next.js app without building everything from scratch.