How To Authenticate Users in Nextjs With NextAuth App Router VS Pages Router

Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

How to Authenticate Users in Next.

js With NextAuth –
App Router VS Pages Router
freecodecamp.org/news/how-to-authenticate-users-with-nextauth-in-nextjs-app-and-pages-router

freeCodeCamp July 3, 2023

By Njoku Samson Ebere

Authentication is a key security feature of any application. But it can be complex to


implement properly.

This tutorial will show you an easy and secure way to handle authentication in your apps. It
involves allowing trusted organizations (such as Google, Facebook, Github, and so on) to
authenticate your users while you focus on building important features in your app.

You will learn how to do this using Nextjs and NextAuth step by step.

You should find this article helpful if you're new to NextAuth. But if you already know how to
set up authentication with the Nextjs Page router and you're still trying to transition to the
Nextjs App router, then this is for you, too.

Here's a video I made that you can use to supplement what you learn here.

Prerequisites

1/29
You need to know the basics of Next.js and Prisma to benefit from this tutorial.

You can catch up on the official Nextjs and Prisma documentation.

What is NextAuth?
NextAuth is an open-source authentication solution for Nextjs applications. It is gradually
being developed to provide solutions for every framework or library on the web. You can find
more details on the Authjs website.

You can think about NextAuth as an intermediary between your application and established
authentication systems. So instead of re-inventing the wheel, you can add this solution to
yours and keep building your application.

The cool thing about this tool is that you do not have to pay money to use it. Just pay
attention. :)

How to Setup the Project


NexthAuth gives you access to many organizations called providers. These organizations
provide some credentials for you to use their authentication system.

This tutorial will cover three of them: Google, GitHub, and Email.

So you'll need to access credentials for each of these providers and bootstrap a boilerplate
for Nextjs.

How to Get Google Credentials

You can follow the steps below to get your Google Client ID and Client Secret.

Log in to Google Console:

2/29
Click on the menu icon by the top-left corner. Select API & Services and then choose
Credentials.

The screen below comes up. Click on Create Project:

3/29
The page that follows is the form below:

Enter the name of your application and click Create. You will be redirected to the
Credentials page:

4/29
Click on the Create Credentials button and select the OAuth client ID option:

You have to configure your consent screen to create an OAuth client ID. Click on the
Configure Consent Screen button to do this:

5/29
Set the User Type to external and click Create:

Next, enter a name, support email, and contact email:

6/29
Scroll to the bottom of the page and click Save and Continue.

The Scopes page now appears. Click Save and Continue. Then click Save and Continue
on the Tests Users page. You will be directed to the Summary page. Review your information
and click Back To Dashboard.

Now try to Create an OAuth client ID, and you should come to the following page:

7/29
Select the Web application option because that is what suits this tutorial

Enter a name for the app:

Add a URI to the Authorized JavaScript origins. Use http://localhost:3000. This is


the landing page of your application. You will add more URIs as you move to production.

Add http://localhost:3000/api/auth/callback/google as one of the Authorized


redirect URIs. This is where users will be directed to complete their login with Google.

8/29
Click Create, and that will produce the Client ID and Client Secret like in the image
below:

Copy them or download the JSON file. You will need them soon.

How to Get GitHub Credentials

9/29
The directions below will guide you to get your GitHub Client ID and Client Secret.

Login to your Github dashboard and click on the profile image at the top-right-hand corner.

Select Settings in the drop-down menu:

In the page that follows, scroll down and select Developer Settings:

10/29
Click on OAuth Apps on the next page and choose to Register a New Application:

Fill out the form that you see on the page that follows:

Application name - auth app


Homepage URL - http://localhost:3000/
Authorization callback URL - http://localhost:3000/api/auth

11/29
Click on the Register Application button. A new page appears with the GITHUB_ID and
GITHUB_SECRET:

Click on Generate a new client secret to see the GITHUB_SECRET.

How to Get Email Credentials

12/29
You can use any email vendor that provides SMTP services. This tutorial will use Gmail. You
can check out Mailgun, SendGrid, and others.

You will need the following details:

EMAIL_SERVER_HOST
EMAIL_SERVER_PORT
EMAIL_SERVER_USER
EMAIL_SERVER_PASSWORD
EMAIL_FROM

The following steps will lead you to your EMAIL_SERVER_PASSWORD:

Log in to your Gmail account. Click on your profile image. It will drop down a menu.

Click on the Manage your Google Account button. You will be redirected to the page below:

13/29
Click on Security on the side menu. The following page will appear.

You will need to set up 2-Step Verification for this process to work. If you have yours done
already, click on it.

It will require your password, after which you will be redirected to the following page:

14/29
Scroll to the bottom and click on App passwords, as in the image above. The page that
shows will look like the image below:

Select an App and a device from the drop-down and click on the Generate button:

15/29
That will now generate a 16-digit text like this:

Your Email credentials will be as follows:

EMAIL_SERVER_HOST="smtp.gmail.com"
EMAIL_SERVER_PORT=465
EMAIL_SERVER_USER="". An example is “[email protected]
EMAIL_SERVER_PASSWORD=""

16/29
EMAIL_FROM="". This email doesn’t have to be in existence.

How to Bootstrap a Next.js Project

You will create 2 Next.js boilerplates. One will use the page router, while the other will work
with the app router.

Page Router

Run the following command to create a Next.js project:

npx create-next-app@latest

You will get multiple prompts. Your answers should be as follows:

What is your project named? page_router_tutorial


Would you like to use TypeScript with this project? No
Would you like to use ESLint with this project? No
Would you like to use Tailwind CSS with this project? No
Would you like to use `src/` directory with this project? No
Use App Router (recommended)? No
Would you like to customize the default import alias? No

You will now have a project created with a pages directory like this:

17/29
App Router

Run the following command to create a Next.js project:

npx create-next-app@latest

You will get multiple prompts. Your answers should be as follows:

18/29
What is your project named? app_router_tutorial
Would you like to use TypeScript with this project? No
Would you like to use ESLint with this project? No
Would you like to use Tailwind CSS with this project? No
Would you like to use `src/` directory with this project? No
Use App Router (recommended)? Yes
Would you like to customize the default import alias? No

You will now have a project created with an app directory like this:

19/29
Everything is now set. You will now begin creating the authentication application.

How to Setup Prisma and NextAuth on the Page and App Router
This section will focus on processes that didn’t change with the release of Next.js 13. So
everything you will do in this section will be applied to both the page_router_tutorial and
app_router_tutorial projects.

20/29
You will do the following:

Install Dependencies
Create and migrate a database model
Add the credentials that you got in the previous segment to a file

How to Install Dependencies

The command below will install all the modules for the project:

npm i next-auth prisma nodemailer faunadb @next-auth/prisma-adapter

It adds NextAuth, Prisma, Node Mailer, Fauna DB, and Prisma Adapter modules to the
project.

How to Create and Migrate a Database Model

A database model defines how tables in the database communicate with each other. You will
create that in this part.

Begin by running the following command:

npx prisma init

It creates a Prisma directory with a file inside called schema.prisma and a .env file in the
project’s root folder. The file will contain your model definition.

Currently, the file content looks like this:

// This is your Prisma schema file,


// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

This tutorial will use the Postgres database as indicated in the code above. The .env file has
the DATABASE_URL that you need to replace with your own. Do not forget to do that to avoid
bugs later in the project.

Add the code below to the schema.prisma file:

21/29
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
oauth_token_secret String?
oauth_token String?

user User @relation(fields: [userId], references: [id], onDelete: Cascade)

@@unique([provider, providerAccountId])
}

model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete:
Cascade)
}

model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}

model VerificationToken {
identifier String
token String @unique
expires DateTime

@@unique([identifier, token])
}

This defines four (4) tables: Account, User, Session, and VerificationToken. The model
shows that a user can have multiple accounts, and each account may be logged into many
places (sessions). The VerificationToken table is for verifying a user.

22/29
It is now time to create the tables in the database. Run the command below to make it
happen:

npx prisma migrate dev

You can then check your database dashboard for the new tables.

You can manage your database from the browser using Prisma by executing the command
below:

npx prisma studio

How to Add Credentials to the .env File

The .env file will hold all the details of your providers and other items. These are the
credentials:

EMAIL_SERVER_USER
EMAIL_SERVER_PASSWORD
EMAIL_SERVER_HOST
EMAIL_SERVER_PORT
EMAIL_FROM

GITHUB_ID

GITHUB_SECRET

GOOGLE_CLIENT_ID

GOOGLE_CLIENT_SECRET

Aside from these that you already know, you need two more:

NEXTAUTH_SECRET
NEXTAUTH_URL

NEXTAUTH_SECRET can be anything you choose. However, you want something hard to
predict. Run the following command to get a very random string:

openssl rand -base64 32

Use the output as the NEXTAUTH_SECRET.

NEXTAUTH_URL is the base URL of your project. Since the project is still in development, the
NEXTAUTH_URL is http://localhost:3000.

Here is what your .env file should look like this:

23/29
DATABASE_URL="postgres://postgres:[email protected].
co:5432/postgres"

EMAIL_SERVER_HOST="smtp.gmail.com"
EMAIL_SERVER_PORT=465
EMAIL_SERVER_USER="[email protected]"
EMAIL_SERVER_PASSWORD="cnbpfzfrjnxvfgcv"
EMAIL_FROM="[email protected]"

GOOGLE_CLIENT_ID="196506336558-
lh9qhavsi224v00n7q6ggn1f6cur9epr.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="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"

GITHUB_ID="11a8144f2897384cfedf"
GITHUB_SECRET="6599042d48110bbda9fcd1ec6ede61f4320adc9d"

NEXTAUTH_SECRET="YegyDIZNJPqxOkGS4K0F/o9l3SjCxCUR4Q/45rGyOtA="
NEXTAUTH_URL="http://localhost:3000"

That concludes what is the same process for both projects. The following section will now
focus on the page_router_tutorial directory.

How to Create Authentication with the Next.js Page Router


Now I'll go through what you need to do in the page_router_tutorial folder. Follow the
steps below:

Make a folder called auth in the pages/api/ directory. Create a file in the pages/api/auth
directory and name it [...nextauth].js.

Import PrismaAdapter, PrismaClient, and NextAuth:

import { PrismaAdapter } from '@next-auth/prisma-adapter';


import { PrismaClient } from '@prisma/client';
import NextAuth from "next-auth";

Also, import the providers like this:

import EmailProvider from "next-auth/providers/email";


import GitHubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";

Instantiate the PrismaClient and export NextAuth as default. Use the code below:

const prisma = new PrismaClient();

export default NextAuth();

This code will automatically create and handle the API routes for authentication.

24/29
Next, export a NextAuth function and add the adapter to it like this:

export default NextAuth({


providers: [...],
adapter: PrismaAdapter(prisma),
});

The providers key is an array of functions, where each one is the provider that you want to
add to your project. You are to add three of them, so your code should look like this:

import { PrismaAdapter } from "@next-auth/prisma-adapter";


import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

export default NextAuth({


providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD,
},
},
from: process.env.EMAIL_FROM,
}),
],
adapter: PrismaAdapter(prisma),
});

That is all you need to create an authentication application using Next.js and NextAuth.

Start the local server by running the following command:

npm run dev

Navigate to http://localhost:3000/api/auth/signin, and you will be on this page:

25/29
Voilà...Surprise! Surprise! Surprise!

You didn’t create any UI, so where did this UI come from?

Now that is the beauty of NextAuth. It creates endpoints and an accompanying UI for each
provider. You don’t have to sweat it, but you can use your UI.

How to Test the Page Router Authentication

The following videos demonstrate how the authentication app you built works:

Google Provider
GitHub Provider
Email Provider - Magic Link
Signout

NextAuth also provides a signout functionality. Navigate to


http://localhost:3000/api/auth/signout.

Click on the Signout button that shows when the page is done loading:

In this section, you learned how to build a Next.js authentication application using the pages
routing pattern. You can find the code for this segment on GitHub:
https://github.com/EBEREGIT/nextjs-nextauth-tut/tree/main/page_router_tutorial.

26/29
But Next.js version 13 was released a while ago and has gotten stable. It comes with the app
routing pattern, and Next.js developers are advised to embrace it since the pages router may
become deprecated soon.

You'll see how to set up Next.js authentication using the app routing pattern in the next
segment.

How to Implement Authentication with the Next.js App Router


This section will show a slightly different and maybe effortless way to implement
authentication with the app router.

You will now turn your attention to the app_router_tutorial folder.

Do not forget to set up Prisma and NextAuth as you did in the previous section for the
page_router_tutorial project.

Now, do the following:

Create an api folder in the app directory.

Make a folder called auth in the app/api/ directory.

Make a folder called [...nextauth] in the app/api/auth directory

Create a file in the [...nextauth] folder called route.js. This is in line with Nextjs 13 Route
Handlers directive.

In the file, import PrismaAdapter, PrismaClient, NextAuth, and the providers like this:

import { PrismaAdapter } from '@next-auth/prisma-adapter';


import { PrismaClient } from '@prisma/client';
import NextAuth from "next-auth";

import EmailProvider from "next-auth/providers/email";


import GitHubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";

Instantiate the PrismaClient:

const prisma = new PrismaClient();

Create a handler function to run the NextAuth configurations with the code below:

const handler = NextAuth(...);

Pass the providers and adapter as one argument into the NextAuth method. Type the
following code:

27/29
const handler = NextAuth({
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD,
},
},
from: process.env.EMAIL_FROM,
}),
],
adapter: PrismaAdapter(prisma),
});

Finally, export the handler with the following line of code:

export { handler as GET, handler as POST };

That is all you need for the authentication to work with the app router.

You will have the same interface as in the previous section if you navigate to
http://localhost:3000/api/auth/signin.

The code for this section is on GitHub: https://github.com/EBEREGIT/nextjs-nextauth-


tut/tree/main/app_router_tutorial.

How to Test the App Router Authentication


Testing the app router authentication follows the same procedure as in the page router.

Conclusion
Implementing authentication can be difficult. But with these helpful tools, it can only get
better. This tutorial aimed to teach how to implement authentication using NextAuth both in
the Next.js pages and app router.

28/29
You saw how to set up Prisma and NextAuth in any Next.js project. You also learned the
difference between Next.js pages and app routing patterns and how to implement the
NextAuth authentication logic.

This tutorial just scratched the surface, but it gives you an angle to start building personal
projects. Please check out the documentation below to keep learning.

React
Next
faunadb
NextAuth
Prisma
Postgres

😊
All the code for this tutorial is one GitHub: https://github.com/EBEREGIT/nextjs-nextauth-tut.
Please leave a star .

If you read this far, thank the author to show them you care.

Learn to code for free. freeCodeCamp's open source curriculum has helped more than
40,000 people get jobs as developers. Get started

29/29

You might also like