0% found this document useful (0 votes)
36 views

Next - Js 13 Authentication With NextAuth - Js (App Router, TypeScript) - Stackademic

Next.js 13 Authentication with NextAuth.js

Uploaded by

guilhermezsimoni
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

Next - Js 13 Authentication With NextAuth - Js (App Router, TypeScript) - Stackademic

Next.js 13 Authentication with NextAuth.js

Uploaded by

guilhermezsimoni
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Get unlimited access to the best of Medium for less than $1/week.

Become a member

Next.js 13 Authentication with NextAuth.js(App


Router, TypeScript)
Hyewon Kim · Follow
Published in Stackademic
6 min read · Aug 15

Listen Share More

Photo by James Wiseman on Unsplash

The NextAuth.js is a 3rd party library designed to facilitate the implementation of


login functionality on pages built using Next.js.
It provides relevant features to make the process of implementing login easier. For
more detailed information, you can refer to next-auth introduction.

Why NextAuth?
The initial adoption of this library stemmed from its provision of a Provider,
streamlining the implementation of login services based on the OAuth
authentication protocol.

At the time of integrating the login feature, my team was in the midst of testing a
web service, prompting the need for a rapid development approach. What
particularly resonated with us was the ability to focus solely on the core login logic,
thanks to the library’s user-friendly features.

The ability to easily manage and integrate social login functionalities like Google,
Facebook, and Github was also a significant factor in using this library.

Of paramount importance in the realm of login functionality is security. To address


this concern, the issuance of JSON Web Tokens (JWTs) for authentication, along
with their secure storage within the browser post-login, was a critical necessity.

Let’s get started!

Installation
First, set up your Next.js project, and then proceed with installing the next-auth
library.

npm create next-app next-auth-test


npm i next-auth

// or

yarn create next-app next-auth-test


yarn add next-auth

Setting up next-auth
Create an “auth” folder and a file named “route.ts” within “app/api/auth/[…
nextauth]/route.ts” directory.

This code is from official next-auth website (https://next-


auth.js.org/providers/credentials).
import NextAuth from "next-auth/next";
import CredentialsProvider from "next-auth/providers/credentials";

const handler = NextAuth({

providers: [
CredentialsProvider({
// The name to display on the sign in form (e.g. "Sign in with...")
name: "Credentials",
// `credentials` is used to generate a form on the sign in page.
// You can specify which fields should be submitted, by adding keys to the
// e.g. domain, username, password, 2FA token, etc.
// You can pass any HTML attribute to the <input> tag through the object.
credentials: {
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
// Add logic here to look up the user from the credentials supplied
const user = { id: "1", name: "J Smith", email: "[email protected]" }

if (user) {
// Any object returned will be saved in `user` property of the JWT
return user
} else {
// If you return null then an error will be displayed advising the user
return null

// You can also Reject this callback with an Error thus the user will b
}
}
})
],

export { handler as GET, handler as POST };

And then write the .env file as follows:

NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=yoursecretcode
In previous versions of Next.js, placing the […nextauth].js file under the
pages/api/auth directory was sufficient for functionality.

However, with Next.js version 13, following the updated App Router structure, you
should create a route.js file under the app/api/auth/[…nextauth] directory if you
working with APIs like NextAuth.

If you’re using TypeScript, you can utilize the .ts extension.

Upon closer inspection, you might notice a distinctive export syntax employed at the
end. This syntax is part of the ES6 module export feature, introducing a fresh
approach to designate the exported module’s name using the ‘as’ keyword. This
approach serves a pivotal role in facilitating the execution of handler functions via
either the GET or POST methods.

This importance stems from Next.js 13’s strong recommendation to export modules
using the GET and POST methods. By exporting the handler object as illustrated
above, you unlock the capability to import it in a manner that aligns precisely with
your intended use.

This empowers you to seamlessly tailor your import approach to either GET or
POST, adhering harmoniously to Next.js 13’s directive to emphasize GET and POST
methods for exports.

Within the “providers” section, you have the flexibility to incorporate various
options. In the provided code, we’ve chosen to use the CredentialsProvider. This
provider comprises several key components.

To start, there’s the “name” section, followed by the “credentials” section. This
“credentials” part directly corresponds to the content within the login form.

Lastly, we encounter an asynchronous function known as “authorize”. Within this


function, a thorough validation of the email and password elements takes place. If
the validation proves successful, the function returns a user object. Conversely, if
the validation fails, it returns null.

NextAuth provides a built-in login form, and when you navigate to the
“/api/auth/signin” URL, you’ll encounter a login form like below.
When a login is successful, the user’s details are stored within the session. To use
this information, we need to envelop the component with the SessionProvider.

So, in the layout.ts file, encase the children element with the SessionProvider, like
this:

export default function RootLayout({


children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<SessionProvider>{children}</SessionProvider>
</body>
</html>
);
}

page.tsx

export default function Home() {


const { data: session } = useSession();
if (session && session.user) {
console.log("session.user", session?.user);
return (
<button
onClick={() => signOut()}
>
{session.user.name} Sign Out
</button>
);
}

return (
<button
onClick={() => signIn()}
>
SignIn
</button>
);
}

Now, when there’s an active session after a successful login, display the logout
button. Conversely, when no session exists, show the login button.

That’s it!

And if you intend to show your own custom signin page, simply add the pages code
in the route.ts file like below:

const handler = NextAuth({


pages: {
signIn: "/auth/signin",
},

providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
...

If you intend to restrict access to specific pages only for logged-in users, you can
achieve this by adding middleware.ts file as below.
export { default } from "next-auth/middleware";

export const config = {


matcher: ["/home", "/user/:path*"],
};

Also, If you’re concerned about security, you can also include a token in the session
object. However, when working with TypeScript, you’ll need to define the session
type.

You can achieve this by creating a file named “next-auth.d.ts,” as shown below. In
my case, I included a User object within the session, containing information such as
accessToken, refreshToken, and accessTokenExpires.

import "next-auth";

declare module "next-auth" {


interface User {
id: number;
email: string;
name: string;
role: string;
accessToken: string;
refreshToken: string;
accessTokenExpires: number;
}

interface Session extends DefaultSession {


user: User;
expires: string;
error: string;
}
}

Open in app

Search

export const authOptions: NextAuthOptions = {


providers: [
...
],
callbacks: {
async jwt({ token, user, session }) {
// the processing of JWT occurs before handling sessions.
console.log("jwt callback ", { token, user, session });

if (user) {
token.accessToken = user.accessToken;
token.refreshToken = user.refreshToken;
token.accessTokenExpires = user.accessTokenExpires;
token.role = user.role;
token.id = user.id;
}

return token;
},

// The session receives the token from JWT


async session({ session, token, user }) {
console.log("session callback ", { token, user, session });

return {
...session,
user: {
...session.user,
accessToken: token.accessToken as string,
refreshToken: token.refreshToken as string,
role: token.role,
id: token.id,
},
error: token.error,
};
},
},

...

};

Once the providers are executed, the callback is subsequently triggered. This
callback function is called whenever the page is refreshed.

Concluding our exploration, we’ve delved into the straightforward implementation


of social login using next-auth. Beyond just configuring providers, this library offers
a wealth of capabilities, from integrating with databases for user data storage to
configuring settings related to login success and more. The versatility it brings
makes it an indispensable tool.
With its user-friendly design, next-auth simplifies the process of integrating social
login within Next.js projects. It’s a recommendation worth considering for those
seeking to swiftly implement authentication features while focusing on other
development aspects.

For those desiring more comprehensive information, I recommend exploring the


official website for additional resources.

Thank you for reading until the end. Please consider following the writer and this
publication. Visit Stackademic to find out more about how we are democratizing free
programming education around the world.

Nextauth Nextjs Nextjs 13 Coding Programming

Follow

Written by Hyewon Kim


7 Followers · Writer for Stackademic

Full Stack Web Developer

More from Hyewon Kim and Stackademic


Hyewon Kim

[Leetcode] Java #20 Valid Parentheses (What is a Stack?)


Environment: Java

3 min read · Mar 20

Parvez Ahmed in Stackademic

Using ChatGPT For Web Scraping: A Practical Guide

You might also like