Integrate authentication into Next.js
This guide shows how to create a simple Next.js application and secure it with authentication powered by Ory. You can use this guide with both The Ory Network and self-hosted Ory software.
This guide is perfect for you if:
- You have Next.js installed.
- You want to build an app using Next.js.
- You want to give access to your application to signed-in users only.
Before you start, watch this video to see the user flow you're going to implement:
You can find the code of the sample application here.
Create Next.js app
First we create a new Next.js project:
npx create-next-app@latest --typescript
cd <your-project-directory>
Install Ory
Ory provides integration tools that quickly combine Ory with Next.js. Let's install Ory's SDK, used to make API calls to Ory, and Ory's Integration Tools for JavaScript frameworks:
npm i --save @ory/integrations @ory/client
and create a special route in [...paths].js
at pages/api/.ory/
.
// @ory/integrations offers a package for integrating with Next.js.
import { config, createApiHandler } from "@ory/integrations/next-edge"
// We need to export the config.
export { config }
// And create the Ory Network API "bridge".
export default createApiHandler({
fallbackToPlayground: true,
dontUseTldForCookieDomain: true,
})
This route connects your Next.js app with Ory's APIs and ensures that all cookies and credentials are set up. Without it, your Next.js application won't be able to talk to Ory's APIs.
Require login to access the home page
Next we add a session check to the default home page of the Next.js example application.The highlighted code is what we added to check whether the user is signed in, and redirect them to the login page if not:
import Head from "next/head"
import Image from "next/image"
import styles from "../styles/Home.module.css"
import { useEffect, useState } from "react"
import { useRouter } from "next/router"
import { Configuration, FrontendApi, Session, Identity } from "@ory/client"
import { edgeConfig } from "@ory/integrations/next"
const ory = new FrontendApi(new Configuration(edgeConfig))
// Returns either the email or the username depending on the user's Identity Schema
const getUserName = (identity: Identity) =>
identity.traits.email || identity.traits.username
const Home = () => {
const router = useRouter()
const [session, setSession] = useState<Session | undefined>()
const [logoutUrl, setLogoutUrl] = useState<string | undefined>()
useEffect(() => {
ory
.toSession()
.then(({ data }) => {
// User has a session!
setSession(data)
// Create a logout url
ory.createBrowserLogoutFlow().then(({ data }) => {
setLogoutUrl(data.logout_url)
})
})
.catch(() => {
// Redirect to login page
return router.push(edgeConfig.basePath + "/ui/login")
})
}, [router])
if (!session) {
// Still loading
return null
}
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to{" "}
<a href="https://nextjs.org">
Next.js,{" "}
{
getUserName(session?.identity)
}
!
</a>
</h1>
<p className={styles.description}>
<a href={logoutUrl}>Log out</a>
</p>
<p className={styles.description}>
Get started by editing{" "}
<code className={styles.code}>pages/index.tsx</code>
</p>
<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h2>Documentation →</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>
<a href="https://nextjs.org/learn" className={styles.card}>
<h2>Learn →</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>
<a
href="https://github.com/vercel/next.js/tree/canary/examples"
className={styles.card}
>
<h2>Examples →</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h2>Deploy →</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</a>
</div>
</main>
<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{" "}
<span className={styles.logo}>
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
)
}
export default Home
Run your Next.js app
Great, that's it. Let's run your application. Set up your environment variables to connect with Ory's APIs
- macOS
- Linux
- Windows CMD
- Windows Powershell
- Self-Hosted Ory Kratos
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
export ORY_SDK_URL=https://{project.slug}.projects.oryapis.com
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
export ORY_SDK_URL=https://{project.slug}.projects.oryapis.com
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
set ORY_SDK_URL=https://{project.slug}.projects.oryapis.com
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
$Env:ORY_SDK_URL = "https://{project.slug}.projects.oryapis.com"
Clone and run Ory Kratos locally
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
and set the environment variable to the exposed port:
export ORY_SDK_URL=http://localhost:4433
and start the Next.js development server:
npm run dev
Then open http://localhost:3000 in your browser. are presented with Ory's Sign In page. Let's click on sign up and create your first user.
Go to production
Release your app bundled with Ory to production using:
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
npx vercel deploy --prod -e ORY_SDK_URL=https://{project.slug}.projects.oryapis.com