What is NextAuth.js
NextAuth.js is a complete open-source authentication solution for Next.js applications. It simplifies sign-in services by managing the authentication and authorization process of OAuth Providers and custom in house sign-in services. OAuth aka Open Authentication is a standard authorization protocol through which providers can allow third parties to securely access their APIs within the limits that they set. For example, if your application wanted access to Google or Facebook API's, this would be done through OAuth and the process of completing OAuth authentication is managed by NextAuth.js. In addition to managing OAuth authentication, NextAuth.js allows your application to create its own custom sign-in service (i.e the classic username and password) and manage that as well.
Install Packages
This guide is going to skip over setting up a Next.js application, but the simplest way to get started is to run:
npx create-next-app
# or
yarn create next-app
After you have completed your application setup, you should install NextAuth.js to your application by running the following:
npm install next-auth
# or
yarn add next-auth
Setup Application
To setup NextAuth.js in your application there are couple of steps that need to be completed. Within the pages/api
directory in your NextJS app create a new auth
directory and add the following initialization file: [...nextauth].js
. Within this file import NextAuth from "next-auth"
and export your authentication options to NextAuth. The only required options are the providers, an array of authentication providers for signing in either custom or third party. Additionally, you will need to include a couple of environment variables for NextAuth including the NEXTAUTH_SECRET
and for production the NEXTAUTH_URL
and any OAuth Provider client id or client secret environment variables.
// src/pages/api/auth/[...nextauth].js
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
],
});
OAuthToken Setup
In this example we are using Google as our OAuth Provider, hence we are going to need Google Client ID and Google Client Secret Tokens. You can obtain these tokens through the Google Cloud Platform. Under APIs & Services you can generate your OAuth credentials which once generated allow your application to access the Google APIs. Copy your clientId and clientSecret tokens and place them in your .env
file. If you are using Vercel as your hosting platform you can use their interface in production to specify your tokens.
NEXTAUTH_SECRET = < NEXT_AUTH_TOKEN >
GOOGLE_CLIENT_ID = < GOOGLE_CLIENT_ID_TOKEN >
GOOGLE_CLIENT_SECRET = < GOOGLE_CLIENT_SECRET_TOKEN >
Authorization Context
The authorization status of your users is provided through the useSession
hook and requires that you set the SessionProvider
above any components that require authorization.
// src/pages/_app.js
import { SessionProvider } from "next-auth/react";
export default function MyApp({ Component, pageProps }) {
return (
<SessionProvider session={pageProps.session}>
<Component {...pageProps} />
</SessionProvider>
);
}
Authorize Users
Once you have completed setting up the application, you can test the authorization functionality of your pages. For testing the signIn and signOut functionality, NextAuth.js provides signIn
and signOut
client side functions. The signIn
function without arguments, will redirect to the NextAuth.js sign-in page. If you include the provider id as an argument to this function then you will skip the sign-in page and move directly to the Provider sign-in page. The signOut
function takes an optional argument object with property callbackUrl
which if provided will redirect the user to the specified route, otherwise it will reload the page in browser.
// src/components/Header.js
import React from "react";
import { signIn, signOut, useSession } from "next-auth/react";
import { H2, FilledButton } from "components/UI";
export default function Header() {
const { data, status } = useSession();
return (
<header>
<H2 inline>Hello {data?.user?.name}</H2>
{status === "unauthenticated" ? (
<FilledButton onClick={() => signIn("google")}>Sign In</FilledButton>
) : (
<FilledButton onClick={() => signOut()}>Sign Out</FilledButton>
)}
</header>
);
}
NextAuth provides the useSession
hook and returns an object of two values: data
and status
. Data contains a Session
object if the user is signed in and status returns either "loading" | "authenticated" | "unauthenticated"
based on the three possible session states. useSession
accepts params such as required
and an onUnauthenticated
function that triggers when the user is not authenticated. You can use these values to signal permission granted for certain actions, routes, views for your frontend components or trigger warnings or redirects if not granted.
// src/pages/user.js
import React from "react";
import { useRouter } from "next/router";
import { useSession } from "next-auth/react";
import { H1, Container } from "components/UI";
import { Header } from "components/Header";
export default function User() {
const router = useRouter();
const { data } = useSession({
required: true,
onUnauthenticated() {
router.replace("/auth/signin");
},
});
return (
<Container>
<Header />
<H1>{data?.user?.name}</H1>
</Container>
);
}
Summary
You learned how to setup your NextJs application using NextAuth.js and Google OAuth Provider. You were also shown examples of how NextAUth.js makes it very simple to manage the authorization state of your users using the useSession
hook and signIn
and signOut
functions.
Packages
"dependencies": {
"next": "12.1.0",
"next-auth": "^4.2.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"styled-components": "^5.3.3"
},