Add authentication and user management to your Next.js React app using the new Next.js Edge Runtime and the Ory Kratos open source project!
Ory Kratos Open Source Identity Platform
Ory Kratos is a full-featured, free, and open source authentication and identity management platform. It supports multi-factor authentication with FIDO2, TOTP, and OTP; Social Sign In, custom identity models; registration, profile management, account recovery, administrative user management and so much more! In contrast to other identity systems, Ory Kratos enables you to build your own login, registration, account settings, account verification (e.g. email, phone, activate account), account verification (e.g. reset password) user interfaces and user flows using dead-simple APIs.
This guide focuses on writing your own UI using Ory Kratos' APIs. If you are interested in just adding login and authentication to your app, check out Add Authentication to your Next.js / React Single Page Application (SPA)
Before we start, let's get some terminology out of the way:
- At Ory, identity can mean any actor in a system (user, robot, service account,
...). The term
user
always refers to a human being sitting in front of a browser or mobile app. - A session refers to a user's session in a browser or mobile app after they have authenticated.
- Self-Service refers to flows the user can do on their own - such as login, registration, and so on. It does not require administrative / support intervention.
Add Login to your React / NextJS
If you want to see a live demo right away, check out this app in action.
The code for this app is available on GitHub. To give it a spin, clone it and run the following commands:
git clone https://github.com/ory/kratos-selfservice-ui-react-nextjs.git
cd kratos-selfservice-ui-react-nextjs
npm i
To use your own Ory Kratos instance, you can use the ORY_SDK_URL
environment
variable. To get started we recommend to run Ory Kratos in an Ory Project, which
is free for developers. You can create a new project on
console.ory.sh or you
via the Ory CLI. Install the
CLI with the package manager of your choice on
Linux,
macOs, or
Windows.
Create a new developer project with just two commands:
# Download the Ory CLI to your local directory:
bash <(curl https://raw.githubusercontent.com/ory/meta/master/install.sh) -b . ory
# install Ory CLI using cURl
./ory auth
# Log into an existing account or create a new one
./ory create project --name <your-project-name>
# Create a new project
After the project has been created the CLI displays the project details:
Project created successfully!
ID a0c23a9d-bd3b-4a20-a6c0-00a1ada73f49
SLUG laughing-ardinghelli-cvaggbj1hi
STATE running
NAME Example
Copy the SLUG
, and set the ORY_SDK_URL
to the
SDK URL of the project you just
created:
# If you run Ory Kratos in the Ory Network:
export ORY_SDK_URL=https://YOUR_PROJECT_SLUG_HERE.projects.oryapis.com
# Start the app
npm run dev
Next head over to http://localhost:3000/ to see the app in action with login, registration - a working user management!
Ory Kratos on your Machine
You can also run Ory Kratos on your own machine and develop in a local environment. A quick way to begin is to run the Ory Kratos Docker quickstart as it includes all the necessary dependencies. You can run Ory Kratos without Docker as well!
git clone --depth 1 --branch master https://github.com/ory/kratos.git
cd kratos
git checkout master
git pull -ff
docker-compose -f quickstart.yml -f contrib/quickstart/kratos/cloud/quickstart.yml up --build --force-recreate -d
In that case, set the ORY_SDK_URL
to your local Ory Kratos instance:
# If you run Ory Kratos locally using the Docker quick start:
export ORY_KRATOS_URL=http://localhost:4455/
# Start the app
npm run dev
Ory Kratos Configuration in the Ory Network
To get everything to work smoothly, we recommend setting the appropriate UI
endpoints in your Ory Network Project under the "User Interface" menu item. If
you are developing locally on port 3000
this would be:
- Login UI:
http://localhost:3000/login
- Registration UI:
http://localhost:3000/registration
- Settings UI:
http://localhost:3000/settings
- Verification UI:
http://localhost:3000/verification
- Recovery UI:
http://localhost:3000/recovery
- Error UI:
http://localhost:3000/error
You can also configure this (like all other Ory configuration) directly in the CLI, for example for the registration UI. Just switch out the flow name to configure the other UIs:
./ory patch project <your-project-id> --replace '/services/identity/config/selfservice/flows/registration/ui_url="http://localhost:3000/registration"'
Also, ensure to set up your redirects correctly, so you end up at the right endpoint after you have signed up or signed in!
We are setting these values to ensure that all flows (e.g. clicking on that password reset link) end up at your application. If you deploy to production, set these values to your production URL!
Start with the Next.js Typescript Template
To start from scratch, initialize the NextJS App and install Ory's SDKs and integration packages:
npx create-next-app --ts
npm i --save @ory/kratos-client @ory/integrations
To make the UI beautiful, we also install Ory's theme package. You can of course use your own styling framework (e.g. Material UI or Tailwind).
npm i --save @ory/themes
We also want to send notifications to users in case something goes wrong. For that, we will install React Toastify:
npm install --save react-toastify
Adding Next.js Edge Function to Integrate with Ory Kratos
To make everything run smoothly, we will add Ory's integration library and
include it in Next.js Edge Runtime. To do so, add a new file under
pages/api/.ory/[...paths].ts
with the following contents:
Setting up the SDK to interact with the Ory Network's APIs is just a few lines of code:
Rendering the Registration Form
Great, now all the preconditions are met! Let's start with the first page we want to implement: the registration form!
Preparing the Registration Page
First we need to initialize the state and get the Self-Service Registration Flow ID from the URL:
Initializing or Fetching a Registration Flow
Next, we create an effect which will fetch the registration flow and set the state. The registration flow contains information about the registration form, e.g. the fields and validation messages to be displayed:
As you can see, if the flow ID is not available, we will initialize a new
registration flow (initializeSelfServiceRegistrationFlowForBrowsers
). If it is
set, we will fetch the flow from the API (getSelfServiceRegistrationFlow
).
Preparing Registration Form Submission
When the user submits the form, we will call the
submitSelfServiceRegistrationFlow
method of the SDK to submit the form:
Rendering the Registration Form
Finally, we render the registration form:
Rendering the Forms
Great, we have now initialized the registration flow and have everything
prepared to render the form. Rendering the form is the same for all flows
(login, registration, recovery, ...). The
<Flow onSubmit={onSubmit} flow={flow} />
React Component
will render the form and handle the form state. The component itself is a bit
longer because we deal with the form state, errors, and the form submission
without any helper tools such as Formik. In essence, it iterates over the
Registration Form's ui.node
values which we received from
initializeSelfServiceRegistrationFlowForBrowsers
/
getSelfServiceRegistrationFlow
earlier:
Then, for each node, it decides what HTML input to render:
The simplest HTML input to render is the hidden input field. Basically you just add the attributes to the HTML element:
Rendering a normal input field looks similar:
Ory Kratos' forms can contain several types of nodes:
These are needed to show, for example, QR codes for TOTP, scripts for WebAuthn, text for recovery codes, buttons for social sign in, and so on!
Dealing With Flow Errors
Usually, Ory Kratos takes care of redirecting to the correct endpoints and showing the right messages. With Single Page Apps though you need to deal with errors yourself. Ory Kratos conveniently returns error IDs which you can use to identify errors and handle accordingly:
Rendering the Recovery Page
Rendering the recovery form is the same as the registration form, but with a few minor changes:
Rendering the Verification Page
Rendering the verification form is the same as the registration form, but with a few minor changes:
Rendering the Account Settings Page
Rendering the account settings form is the same as the registration form, but with a few minor changes:
Rendering the Login Page
The login page is a bit more work to render! That is because we want to support two-step authentication and we need to deal with any two-factor authentication errors by e.g. logging the user out.
Form Rendering Conclusion
That was quite a bit of code, but it's all there is to it! If you do not want to implement these UI screens yourself, use the reference implementations for Ory Kratos instead, or clone this repository and use it as a base for your project!
git clone https://github.com/ory/kratos-selfservice-ui-react-nextjs.git
Deploy to Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js. If you have never deployed on Vercel, check out the Next.js deployment documentation for more details. Deploying the app is easy. Ensure that your build works by running
npm run build
Then, set up your Vercel account and create a new app. You will need to configure your the Ory Network Project SDK URL or the URL of your self-hosted Ory Kratos instance in your Vercel deployment:
By the way! If you want to use separate Ory Kratos deployments for staging, production, and development then use different SDK URLs for the different environments by un/selecting the checkboxes in the Vercel UI:
If you want to call the Ory Network's Admin APIs from your Next.js Edge serverless functions, optionally set up the Ory Personal Access Token:
Next all you need to do is to run the deploy command and connect it to the project you created:
npx vercel deploy --prod
This also works with Vercel PR Preview!
End-to-End Tests
Adding end-to-end tests is also easy! Clone the repository and run the following commands:
git clone https://github.com/ory/kratos-selfservice-ui-react-nextjs.git
cd kratos-selfservice-ui-react-nextjs
npm i
Then, depending on your setup, you can either use Ory Kratos local or in Ory Cloud:
export ORY_KRATOS_URL=https://playground.projects.oryapis.com/
Then, build and start the server
npm run dev
and in a new shell run the end-to-end tests:
npm run test:dev
You can find the full spec file in the cypress/integration/pages.spec.js
file:
The GitHub Action file is also straight forward and contains two configurations, one for running Ory Kratos locally and one for running Ory Kratos in the Ory Network:
Conclusion
Adding login and registration to your Next.js app is a breeze with open source technology like Ory Kratos and Next.js.
We hope you enjoyed this guide and found it helpful! If you have any questions, check out the Ory community on Slack and GitHub!