In this lesson, we are going to walk you through the process of creating a user authentication system using Next.js and Auth.js, which is formerly know as NextAuth.js. In a lot of tutorials, you'll see both names used interchangeably, even in the official documentation, please know that they are referring to the same thing. For this course, we'll stick to Auth.js for consistency.
Auth.js is a user authentication library that simplifies secure integration with databases, email services, OAuth providers, and everything that is required to create a seamless and robust authentication experience for their applications.
Installing Auth.js
To get started, navigate to the root directory of our project and run the following command to install the Auth.js package.
1npm install next-auth@beta
Auth.js requires you to generate a secret key, which will be used to encrypt tokens and email verification hashes. It is very important to keep this secret key secret. Exposing this key will lead to serious security risks.
The key can be generated with the following command:
1npx auth secret --copy
1Need to install the following packages:
2auth@1.2.3
3Ok to proceed? (y)
4📝 Secret generated. It has been copied to your clipboard, paste it to your .env/.env.local file to continue.
5
6AUTH_SECRET="<secret_key>"
This command will generate a key and copy it to your clipboard. You can paste it into the .env
file under the project root directory. Manually create the .env
file if it doesn't exist.
1.
2├── .env <===== This is the file that contains all environmental variables
3├── .gitignore
4├── README.md
5├── eslint.config.mjs
6├── jsconfig.json
7├── next.config.mjs
8├── package-lock.json
9├── package.json
10├── postcss.config.mjs
11├── public
12├── src
13└── tailwind.config.mjs
.env
1AUTH_SECRET="<secret_key>"
Auth.js configurations
Next, we need a place to store all the configurations for Auth.js. There's no fixed way to do this, but we recommend creating an auth.js
file in your project:
1src
2├── app
3│ ├── favicon.ico
4│ ├── globals.css
5│ ├── layout.jsx
6│ └── page.jsx
7├── components
8│ ├── footer.jsx
9│ └── navbar.jsx
10└── libs
11 └── auth.js <===== Configuration file for Auth.js
You can put this auth.js
anywhere you wish. For demonstration purposes, we'll put all miscellaneous documents, including this auth.js
, under src/libs
directory.
Copy and paste the following code into your auth.js
.
libs/auth.js
1import NextAuth from "next-auth";
2
3export const { handlers, signIn, signOut, auth } = NextAuth({
4 providers: [],
5});
Take a closer look at this example, and notice that we are using the NextAuth()
function from the next-auth
package.
This NextAuth()
accepts an object as its input argument, and the object contains all the configurations for Auth.js. We'll talk more about it later.
NextAuth()
also returns several utilities that are essential for creating authentication workflows.
handlers
This is a route handler for Auth.js, which provides an API endpoint for OAuth and email providers.
For example, imagine you have a magic link authentication system where the user provides their email address and clicks the Sign In button. An email gets sent to their inbox with a magic link. The user clicks on the link, it triggers the handler
endpoint provided by Auth.js.
Behind the scenes, Auth.js validates the link, authenticates the user, and manages the session, ensuring a secure and seamless signin process.
signIn
andsignOut
They are two helper functions that allows you sign users in, or sign them out. We'll discuss how to use these helper functions later.
auth
auth
is a universal method used to interact with Auth.js in your app. It is most commonly used to verify if a user is authenticated, refresh the user session, and so on.
Setting up a route handler for Auth.js
Lastly, before we start implementing the authentication system, there is one last thing we must do to finish setting up Auth.js, and that is to take the handler
we discussed above, and place it inside the Next.js routing system so that it is accessible.
Create a route.js
file under src/app/api/auth/[...nextauth]/
:
1src
2├── app
3│ ├── api
4│ │ └── auth
5│ │ └── [...nextauth]
6│ │ └── route.js <=====
7│ ├── favicon.ico
8│ ├── globals.css
9│ ├── layout.jsx
10│ └── page.jsx
11├── components
12│ ├── footer.jsx
13│ └── navbar.jsx
14└── libs
15 └── auth.js
And set up the route handler like this:
app/api/auth/[...nextauth]/route.js
1import { handlers } from "@/libs/auth"; // Referring to the auth.ts we just created
2export const { GET, POST } = handlers;
And that's it, there's not much we need to do here. As long as the handler is accessible, Auth.js will automatically take care of everything else.