Next.js Authentication with Okta and NextAuth.js 4.0
Looking to add authentication to your Next.js application? Considering Okta as your login provider? You have come to the right place! This article covers adding authentication to your Next.js application with NextAuth.js and using Okta as a login provider. All with TypeScript in mind along the way.
If you don’t want to use Okta that’s fine, skip to section 3 to see how to use NextAuth.js with any properly configured provider.
Here’s the GitHub repository where I have all the code mentioned in this article. Also, I think it’s important to note the package versions that this article has been tested against: next 12.3.0, next-auth 4.13.0, react 18.2.0
1. Create A Brand New Next.js App and Install NextAuth.js
npx create-next-app --ts
This creates a brand new Next.js application for us and the
--ts means the starter app will be initialized with TypeScript. Go through the options, name your app, and you’ll have a brand new Next.js app with TypeScript!
Change directories into your new app and the first thing you’ll do is install NextAuth.js. The package is called
npm i firstname.lastname@example.org
I’ve put the explicit
@4.13.0 because that’s the latest version that I have tested for this article. I assume any 4.0 version will work but I wanted you to be aware of what I have explicitly tested against.
❓ What is NextAuth.js? NextAuth.js is an open-source authentication solution created by the community that loves Next.js. It’s built with Next.js in mind the whole way for static, server side, and API route authentication. Check out the NextAuth.js introduction to learn more.
2. Create an OIDC Application in Okta
You need an OIDC application in Okta which you will authenticate against. I did this process using the Okta CLI but it can also be done by logging into Okta.com and creating an app there.
- Install the Okta CLI
- Easily done with Chocolatey
choco install okta
- Easily done with Chocolatey
- If you DO NOT have an account run
okta register. If you DO have an account
- Create your app with
okta apps create
- Take the default app name or rename if you would like
- Choose the Web option for the Type of Application
- Choose Other for the Framework of Application
- Redirect URI:
- Logout Redirect URI:
- You just created your Okta app in the CLI! You will see that a
.okta.envfile was created in your Next.js application. This holds the important environment files that you’ll need.
.okta.env to your .gitignore file. The
.okta.env file contains sensitive information that should not be in source control.
3. Initial NextAuth.js setup & configuration
Now it’s time to get into using the next-auth package you installed and set up Okta as an authentication provider. With NextAuth.js it’s a similar workflow for adding additional providers, but I’ll be sticking with Okta for this example.
- Create a
.env.localfile at the root of your project. This is what the Next.js application will access to get any environment variables. Copy everything over from the
.okta.envinto your new
.env.localbut remove the
exportfrom in front of the variables.
❗ Make sure your
.env.local does not go into source control now that you have put sensative information into it. If you created your app with
npx create next app --ts it should already be in your .gitignore.
- Two more variables need to be added to
SECRETis generated by you. I used https://acte.ltd/utils/randomkeygen and copied the Encryption Key 256 to use for my value.
- Now create a
[...nextauth].tsfile under the
pages/apifolder of your application. This is a special file used by NextAuth.js, that handles the sign-in and sign-out process for your Next.js application. Paste the following code into your file.
- Now we move to the
pages/_app.tsxfile. We need to add a Provider that wraps our entire application here so that the NextAuth.js session data can be shared between components and pages.
At this point, you have authentication setup. What is covered next is the way to use the next-auth package you installed and set up. This will work if you have set up Okta as I showed above or if you have properly set up one or more of the many other providers you can use with NextAuth.js.
4. Adding Authentication to Pages
Now it’s time to look at actually putting content behind authentication in your Next.js pages and API endpoints. Keep in mind this article makes no attempt at having a pretty user interface (UI). The focus is on authentication and I did not want to have any added complexity.
In this section, you will see three authentication implementation patterns:
- Client Side Authentication
- Server Side Authentication
- Next.js API Route Authentication
Client Side Authentication
Authentication on the client side is not usually the best approach. The reason for this is that the data is sent to the client then authentication happens after. The visitor will not technically see any data on the page that they are not allowed to see but has the ability to access it if they really wanted to. Maybe you don’t have super sensitive that allows for client-side authentication.
Below is a code sample for executing client-side authentication for a Next.js page. It has a loading state that displays while the authentication status is being checked and then displayed the proper text and signIn or signOut button respectively.
Notice the awesome
signOut methods passed into the
onClick handlers. These are provided by the
next-auth/react package. These buttons will send users to the
api/auth/[...nextauth].ts route you created and automatically handle the sign in and sign out process for you. It’s that easy to get login work in your application.
💡Only using one login provider? Consider modifying the code to use
signIn('okta') and it will bring users directly to Okta’s login portal. This works for other providers as well, example
Server Side Authentication
Performing authentication server side is preferred. This is because the route will be pre-rendered by the server and only the appropriate content will make it to the client. If authenticated only that portion of the content is sent to the client and the same goes for unauthenticated content.
The below code is a Next.js page with
getServerSideProps indicating the page is using server side rendering (SSR). It may look scary to use
unstable_getServerSession call but that is the recommended method as of now. It is more performant than previous implementations provided NextAuth.js.
Server Side Redirect If Not Authorized
The above code checks the session within
getServerSideProps to see if the user is authenticated. If they are we return the user's name and if they are not they get redirected to the homepage. For this app I do not have a dedicated login page, but if your application has a login page that would be a great place to send people that are not authorized.
💡 What does the
permanent value mean in the redirect? Permanent can be one of two values true or false. If true the redirect will use the 308 status code which instructs clients/search engines to cache the redirect forever, if false will use the 307 status code which is temporary and is not cached.
Next.js API Route Authentication
If you need to add authentication to a Next.js API route you can use the same
unstable_getServerSession that was used above in server side authentication.
If authorized you send them the protected content, otherwise the code sends back and error to the user making the request.
With NextAuth.js authentication in Next.js become much simpler. With a little setup, you can easily add Okta support to your application, and after that initial setup, it’s very easy to add additional providers like GitHub, Google, or even bring in your own database.
You now have all the knowledge you need now to create a Next.js application that has content protected by an authentication layer connected to Okta. Remember server side authentication is the safer method for ensuring visitors only see the content they are supposed to.
Next-auth is a powerful library and I encourage you to explore its more advanced capabilities of it so you can be as informed as possible when it comes to authentication and the security of your application.
Here is the GitHub Repository with all the code from this article.