nodejs-passkeysPasskeys Implementation

Tutorial: How to Add Passkeys to Node.js (Express) App

In this tutorial, we show how to integrate passkeys into a Node.js (Express) app using Corbado's Node.js SDK & UI components for passwordless authentication.

Blog-Post-Author

Lukas

Created: October 16, 2023

Updated: September 16, 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.

Overview#

1. Introduction: Node.js (Express) Passkeys

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

If you want to see the finished code, please have a look at our Node.js (Express) 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 Node.js, Express, 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 Node.js (Express) Passkey Project

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

├── .env # Contains all environment variables └── src ├── views | └── pages | ├── login.ejs # The homepage / login page | └── profile.ejs # The profile page ├── app.ts # The main server file ├── authController.ts # Responsible to retrieve profile information in backend └── routes.ts # The routes for our frontend pages

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

4. Set Up Your Node.js (Express) Project

First, open a new directory, create a package.json and tsconfig.json file and copy our content from package.json as well as from tsconfig.json

Next, install all dependencies:

npm i

That's it for now.

5. Set Up Corbado Passkey Authentication

To set up Corbado passkey authentication in your Node.js (Express) 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 Node.js (Express) 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 "Vanilla 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).

Afterwards, you'll see the relevant HTML / JavaScript code snippets you need to integrate into the 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 Node.js (Express) Project

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 example-passkeys-nodejs

Open the .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:

PROJECT_ID=<your-project-id> API_SECRET=<your-api-secret> FRONTEND_API=<your-frontend-api-url> BACKEND_API=<your-backend-api-url>

5.2 Project Preparation

First, install the Corbado Node.js SDK (if not already done in step 4):

npm i @corbado/node-sdk

To initialize the SDK, we pass our Project ID, API secret as well as both Frontend API and Backend API URLs.

import { Request, Response } from "express"; import { SDK, Config } from "@corbado/node-sdk"; import { config as dotenvConfig } from "dotenv"; dotenvConfig(); const projectID = process.env.PROJECT_ID; const apiSecret = process.env.API_SECRET; const frontendAPI = process.env.FRONTEND_API; const backendAPI = process.env.BACKEND_API; const cboConfig = new Config(projectID!, apiSecret!, frontendAPI!, backendAPI!); const sdk = new SDK(cboConfig);

5.3 Set Up Node.js (Express) Backend

Now, we add two API routes in src/authController.ts delivering HTML to the client.

The homepage / login page is static while the profile route will provide user information to our template which is retrieved via the Corbado Node.js SDK from the short_term_session cookie (represented as JWT).

export function auth(req: Request, res: Response) { res.render("pages/login"); } export async function profile(req: Request, res: Response) { const shortSession = req.cookies.cbo_short_session; if (!shortSession) { res.redirect("/"); } try { const user = await sdk.sessions().validateToken(shortSession); const cboId = user.userId; const identifiers = await sdk .identifiers() .listByUserIdAndType(cboId, "email"); const email = identifiers.identifiers[0].value; res.render("pages/profile", { cboId, email }); } catch (e) { console.log(e); res.redirect("/"); } }

Next, we define our routes in the src/routes.ts file.

import express from "express" import {auth, profile} from "./authController"; const router = express.Router(); router.get("/", auth) router.get("/profile", profile) export default router

Lastly, we'll put everything together in our app.ts file.

We initialize our Node.js (Express) app, use cookieParser to get access to cookie headers, set our template rendering engine to ejs and define our application's port.

import express from 'express'; import {config as dotenvConfig} from "dotenv"; import cookieParser from "cookie-parser"; import authRoutes from "./routes" import {sequelize} from "../models"; dotenvConfig() const app = express(); app.use(cookieParser()) app.set('views', './src/views') app.set('view engine', 'ejs'); const port = 3000;

Now, our backend is finished.

5.4 Create the Homepage to Handle Sign-ups and Logins

We'll create two templates, the first of which will be our homepage / login page under src/views/pages/login.ejs.

We first load the web-js CSS and JavaScript in the head of the document.

Then, we create a div with the id of corbado-auth that we'll use to inject the authentication UI into.

First, load your Corbado project with the setShortSessionCookie: true option so a cookie is created on successful login or sign-up.

Then, mount the authentication UI and pass it a callback which will be executed once the user has logged in.

login.ejs:

<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://unpkg.com/@corbado/web-js@2.9.0/dist/bundle/index.css" /> <script src="https://unpkg.com/@corbado/web-js@2.9.0/dist/bundle/index.js"></script> </head> <body> <div id="corbado-auth"></div> <script type="module"> await Corbado.load({ projectId: "<%= process.env.PROJECT_ID %>", setShortSessionCookie: true }); async function onLoggedIn() { window.location.href = "/profile" } const authElement = document.getElementById('corbado-auth'); //Element where you want to render CorbadoAuth UI Corbado.mountAuthUI(authElement, { onLoggedIn: onLoggedIn, }); </script> </body> </html>

5.5 Create a Profile Route using the Corbado Node.js SDK

Next, let's create the profile page under src/views/pages/profile.ejs.

We render the email and cboId context in the template and attach an event listener to the logout button, which in turn uses the Corbado.logout utility.

profile.ejs:

<!DOCTYPE html> <html> <head> <head> <link rel="stylesheet" href="https://unpkg.com/@corbado/web-js@2.9.0/dist/bundle/index.css" /> <script src="https://unpkg.com/@corbado/web-js@2.9.0/dist/bundle/index.js"></script> </head> </head> <body> <div> <h1>User profile:</h1> <p>Email: <%= email %></p> <p>Name: <%= cboId %></p> <button id="logoutButton"> Logout </button> </div> <script type="module"> await Corbado.load({ projectId: "<%= process.env.PROJECT_ID %>", setShortSessionCookie: true }); document.getElementById("logoutButton").addEventListener("click", async () => { await Corbado.logout() window.location.href = "/" }) </script> </body> </html>

Now, we have our whole application all set up.

5.6 Run the Node.js (Express) Application

Use the following command to run the application:

npm run start

You'll be able to access the application under http://localhost:3000 and see our authentication UI.

Create passkey account component

Create an account and take a look at the profile page under /profile, where you'll be redirected to.

6. Conclusion: Node.js (Express) Passkeys

This tutorial showed how easy it is to add passwordless authentication with passkeys to a Node.js app using Corbado. Besides the passkey-first authentication, Corbado provides simple session management, that we used for a retrieval of basic user data. If you want to read more about how Corbado's session management works, please check the docs here.

Share this article


LinkedInTwitterFacebook

Table of Contents

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