Next.js Passkeys TutorialPasskeys Implementation

How to Implement Passkeys in Next.js Apps

Next.js & Passkeys: This tutorial shows how to integrate passkeys into Next.js apps by implementing passkey-first authentication & session management.

Blog-Post-Author

Lukas

Created: July 4, 2023

Updated: October 9, 2024


We aim to make the Internet a safer place using passkeys. That's why we want to support developers with tutorials on how to implement passkeys.

1. Introduction: Next.js Passkeys#

In this blog post, we’ll explore how to implement Next.js passkeys for secure authentication using Corbado. We'll cover the setup of the Corbado React package for the Next.js frontend part as well as the Corbado Node.js SDK for the Next.js backend part.

If you want to see the finished code, please have a look at our Next.js passkey example repository on GitHub.

The final authentication page will look as follows:

Create passkey account component

2. Prerequisites#

This tutorial assumes basic familiarity with Next.js, HTML, CSS and JavaScript / TypeScript. Moreover, you need to have Node and NPM installed on your machine. Let's dive in!

3. Repository Structure of the Example Next.js Passkey Project#

Let's first discuss the structure of our project (full Next.js passkeys GitHub repo):

next.js/ ├── app/ │ ├── auth/ │ │ └── page.tsx │ ├── profile/ │ │ └── page.tsx │ ├── user-data/ │ │ └── route.ts │ ├── globals.css │ ├── layout.tsx │ ├── page.tsx │ └── _utils/ │ ├── LogoutButton.tsx │ ├── Provider.tsx │ ├── QueryClientWrapper.tsx │ └── nodeSdk.ts └── .env.example

The rest of the files of this project can be ignored for the purpose of this tutorial.

4. Set Up the Next.js Project#

In the following, we explain step-by-step what needs to be done to successfully set up the Next.js project. If you want to see the finished code, please have a look at our Next.js passkey example app repository.

Let's start by initializing a new Next.js project:

npx create-next-app@latest

In the installation guide steps, we select the following:

  • Project name: passkeys-demo-nextjs
  • TypeScript: Yes
  • ESLint: Yes
  • Tailwind CSS: Yes
  • src/ directory: No
  • App Router: Yes
  • Default import alias: No
Slack Icon

Become part of our Passkeys Community for updates and support.

Join

5. Set up Corbado Passkey Authentication#

To set up Corbado passkey authentication in your Next.js project, follow the next steps.

5.1 Set up Your Corbado Account and Project#

Visit the Corbado developer panel to sign up and create your account (you'll see the passkey sign-up in action here!).

Corbado Developer Panel for Next.js Passkeys

After sign-up, a project wizard will guide you through the necessary steps to get everything up and running:

  1. Begin by selecting an appropriate name for your project.
  2. For the product selection, opt for "Corbado Complete".
  3. Register your community license and optionally join our Passkeys Community or subscribe to the Passkeys Substack.
  4. Select "DEV" as your environment.
  5. Choose "Corbado session management" to get a secure and efficient session management besides passkey authentication.
  6. Choose "Web app" as we're building a web application.
  7. Select "Next.js" as your frontend framework.
  8. Provide the Application URL and Relying Party ID. The Application URL is the URL where you embed the Corbado UI component. In this example, we set it to http://localhost:3000. The Relying Party ID is the domain (no protocol, no port and no path) where passkeys should be bound to. Here, it's localhost (you can define both values als in the Settings > General > URLs of the Corbado developer panel).
Ben Gould Testimonial

Ben Gould

Head of Engineering

I’ve built hundreds of integrations in my time, including quite a few with identity providers and I’ve never been so impressed with a developer experience as I have been with Corbado.

10,000+ devs trust Corbado & make the Internet safer with passkeys. Got questions? We’ve written 150+ blog posts on passkeys.

Join Passkeys Community

Afterwards, you'll see the code snippets you need to integrate into the Next.js project. The subsequent sections of this article will explain them in detail.

As another step, we create an API secret which will be needed to request user data from the Corbado backend. Please create an API secret in Settings > Credentials > API secrets.

Corbado Developer Panel: Create API Secret for Next.js

Afterwards, we need to also get the Frontend API and Backend API URLs which we can find in Settings > General.

Screenshot 2024-09-16 at 18.01.13.png

Next, you need to go back to your terminal and should navigate to the root directory of the project:

cd passkeys-demo-nextjs

Create a new .env file at the root of your project. Copy and paste the API secret, Project ID as well as both Frontend API and Backend API URLs (you can obtain it from the Corbado developer panel from Settings > General). The .env file should look like this now:

NEXT_PUBLIC_CORBADO_PROJECT_ID=<your-project-id> CORBADO_API_SECRET=<your-api-secret> CORBADO_FRONTEND_API=<your-frontend-api-url> CORBADO_BACKEND_API=<your-backend-api-url>

Next.js enables the straightforward use of environment variables through process.env.ENV_VARIABLE_NAME. Those variables prefixed with NEXT_PUBLIC_ can be accessed in both client-side and server-side routes, as Next.js automatically embeds these into the JavaScript bundle during the build process.

On the other hand, environment variables without this prefix are treated as a secret and can only be accessed in server-side routes. This is because Next.js does not expose these variables to the client-side to ensure the confidentiality of potentially sensitive information.

To style the application, you can copy our CSS styling or just create your own with tailwind. This is an optional step.

Substack Icon

Subscribe to our Passkeys Substack for the latest news, insights and strategies.

Subscribe

5.2 Next.js Project Preparation#

First of all, we need to install the Corbado React package as well as the Corbado Node.js SDK.

npm install @corbado/react @corbado/node-sdk

Optionally, you can also install the Corbado types for a smoother TypeScript experience:

npm i -D @corbado/types

We now create a wrapper around the <CorbadoProvider/> component to render it on the client-side.

"use client" import { CorbadoProvider } from "@corbado/react" export default function Provider({ children, }: { children: React.ReactNode }) { return ( <CorbadoProvider projectId={process.env.NEXT_PUBLIC_CORBADO_PROJECT_ID!} darkMode='off' setShortSessionCookie={true} > {children} </CorbadoProvider> ) }

We use the setShortSessionCookie setting to create a cookie called cbo_short_session. This cookie is returned after a successful authentication event and is used on backend calls that we'll implement later.

Now, integrate the Provider wrapper into your root layout:

import "./globals.css" import type {Metadata} from "next" import {Inter} from "next/font/google" import CorbadoProvider from "./_utils/Provider" const inter = Inter({subsets: ["latin"]}) export const metadata: Metadata = { title: "Next Corbado Example", description: "Go passwordless with Corbado and Next.js", } export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang='en'> <CorbadoProvider> <body className={inter.className}>{children}</body> </CorbadoProvider> </html> ) }

5.3 Create the Homepage to Handle Sign-ups and Logins#

Clean up the skeleton from the page.tsx file under app/ and display the <CorbadoAuth/> component. Include the 'use client' directive so the page renders on the client-side. It takes an onLoggedIn callback which redirects to /profile in our case.

'use client' import { CorbadoAuth } from "@corbado/react" import { useRouter } from "next/navigation" export default function Auth() { const router = useRouter() const onLoggedIn = () => { router.push("/profile") } return ( <div> <CorbadoAuth onLoggedIn={onLoggedIn} /> </div> ) }

Now, you have successfully implemented everything necessary to handle the sign-up and login.

Debugger Icon

Want to experiment with passkey flows? Try our Passkeys Debugger.

Try for Free

5.4 Use the Corbado Node.js SDK for Backend Authentication#

Let's create a utility to access the Corbado.js Node SDK throughout our application under app/_utils/nodeSdk.ts.

import { Config, SDK } from '@corbado/node-sdk'; const projectID = process.env.NEXT_PUBLIC_CORBADO_PROJECT_ID!; const apiSecret = process.env.CORBADO_API_SECRET!; const frontendAPI = process.env.CORBADO_FRONTEND_API!; const backendAPI = process.env.CORBADO_BACKEND_API!; const cboConfig = new Config(projectID, apiSecret, frontendAPI, backendAPI); const sdk = new SDK(cboConfig); export default function getNodeSDK() { return sdk; }

Now, we have convenient access to the Corbado Node.js SDK throughout our app.

5.5 Create a Profile Route to Show the User's Profile Information#

Additionally, we want to access user information in a server-side rendered route with our profile page. Create a page.tsx file under app/profile/ and access the user's cbo_short_session cookie, which is a JWT. We redirect the user to the / route if he isn't authenticated. If he is authenticated, we render some of his profile information.

import {cookies} from "next/headers"; import getNodeSDK from "@/app/_utils/nodeSdk"; import {redirect} from "next/navigation"; import LogoutButton from "@/app/_utils/LogoutButton"; import PasskeyList from "@/app/_utils/PasskeyList"; // the user data will be retrieved server side export default async function Profile() { const cookieStore = cookies(); const session = cookieStore.get("cbo_short_session"); if (!session) { return redirect("/"); } const sdk = getNodeSDK(); let user; try { user = await sdk.sessions().validateToken(session.value); } catch { return redirect("/"); } return ( <div> <h1>Profile Page</h1> <p> User-ID: {user.getID()}<br/> Email: {user.getEmail()} </p> <LogoutButton/> <PasskeyList/> </div> ) }

As you can see, we also imported a <LogoutButton/> component which needs to be in another file as it utilizes onClick functionality to log the user out. Place this one inside app/_utils/LogoutButton.tsx

'use client' import { useCorbado } from "@corbado/react" import { useRouter } from "next/navigation" export default function LogoutButton() { const { logout } = useCorbado() const router = useRouter() const onLogout = () => { logout() router.push("/") } return ( <button onClick={onLogout}>Logout</button> ) }

Furthermore, we used the <PasskeyList/>, which is a component provided by Corbado to manage a user's passkeys. Here, we need to create a client wrapper once more under app/_utils/PasskeyList.tsx:

"use client" import { PasskeyList as CorbadoPasskeyList } from "@corbado/react"; export default function PasskeyList() { return ( <CorbadoPasskeyList /> ) }

5.6 Run the Next.js Application#

If everything is set up and installed, run the application with

npm run dev

You should see the following screen when navigating to http://localhost:3000:

Create Passkey Account Component

After a successful sign-up / login, you'll see the profile page at http://localhost:3000/profile:

Profile Page Next.js Passkeys

Next.js Icon

Add passkeys to your Next.js app.

Start For Free

6. Conclusion: Next.js Passkeys#

This tutorial showed how easy it is to add passkeys to a Next.js app using Corbado. Besides the easy passkey-first authentication integrated with the React package, Corbado provides simple and secure session management to access protected user data. If you want to read more about how Corbado's session management works, please check the docs here.

Share this article


LinkedInTwitterFacebook

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free