Next - Js 13 Authentication With NextAuth - Js (App Router, TypeScript) - Stackademic
Next - Js 13 Authentication With NextAuth - Js (App Router, TypeScript) - Stackademic
Become a member
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.
Installation
First, set up your Next.js project, and then proceed with installing the next-auth
library.
// or
Setting up next-auth
Create an “auth” folder and a file named “route.ts” within “app/api/auth/[…
nextauth]/route.ts” directory.
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
}
}
})
],
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.
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.
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:
page.tsx
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:
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";
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";
Open in app
Search
if (user) {
token.accessToken = user.accessToken;
token.refreshToken = user.refreshToken;
token.accessTokenExpires = user.accessTokenExpires;
token.role = user.role;
token.id = user.id;
}
return token;
},
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.
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.
Follow