Blog-Post-Header-ImagePasskeys Implementation

How to Build a Vanilla JavaScript Passkey Login

This tutorial shows how to implement passkeys in Vanilla JavaScript using Corbado's Vanilla JavaScript component.

Blog-Post-Author

Nicolai

Created: September 14, 2023

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

In this blog post, well be walking through the process of building a sample application with passkey authentication using Vanilla JavaScript. Well cover the setup of the Corbado Vanilla JavaScript component that simplifies the implementation of passkey login functionality for a seamless user experience.

If you want to see the finished code, please have a look at our sample application repository on GitHub.

The result looks as follows:

Vanilla JavaScript Passkeys Login Page

2. JavaScript Passkey Project Prerequisites

This tutorial assumes basic familiarity with HTML and JavaScript. Lets dive in! Moreover, you need to have Node and NPM installed on your machine (we will use a npm package as web server which you need to run the project).

3. Repository Structure for JavaScript Passkey Project

This repository contains only two HTML files: The login page as well as the profile page which is only accessible once you are logged in (see the full GitHub repo here):

. ├── index.html └── profile.html

4. Set up Your Corbado Account and Project

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

Vanilla JavaScript Passkeys Corbado Sign up Page

In the project setup wizard, begin by selecting an appropriate name for your project. For the product selection, opt for "Corbado Complete". Subsequently, specify your technology stack and select "DEV along with "Corbado session management" options. Afterwards, youll get more foundational setup guidance. The subsequent sections of this article will delve into the integration part.

Next, we navigate to Settings > General > URLs and set the Application URL, Redirect URL and Relying Party ID to the following values (see explanation below - we will use a simple http server to host our HTML files on port 8080):

Vanilla JavaScript Passkeys Application URL Redirect URL Relying Party ID

  • Application URL: Provide the URL where you embedded the Vanilla JavaScript component, http://localhost:8080.
  • Redirect URL (previously): Provide the URL your app should redirect to after successful authentication and which gets sent a short-term session cookie, here: http://localhost:8080/profile. This is only needed if you used the previous web component approach instead of the recent Vanilla JavaScript component approach. In the Vanilla JavaScript component, the redirect is handled by a callback of the CorbadoAuth component.
  • Relying Party ID: Provide the domain (no protocol, no port and no path) where passkeysshould be bound to, here: localhost

5. Create Vanilla HTML / JavaScript App

5.1 Create Passkey Login Page

Create a folder for your project and place an index.html file in it. Inside that file, paste the following HTML code. This includes a script from Corbado which we need in the next steps. This script basically uses the Corbado project ID and mounts the passkey authentication component into a div with the id "corbado-auth":

<!DOCTYPE html> <html> <head> <title>Corbado</title> <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: "pro-2796694128247001826", }) const authElement = document.getElementById('corbado-auth'); Corbado.mountAuthUI(authElement, { onLoggedIn: () => { window.location.href = '/profile.html'; }, isDevMode: true, }); </script> </body> </html>

The most important part here is the authElement which also holds a callback function onLoggedIn that is called when the authentication is successful. In this case, we redirect the user to the /profile page.

5.2 Add Profile Page

After successful authentication, the Corbado Vanilla JavaScript component emits the onLoggedIn callback and the user will be redirected to the /profile page. This page renders basic user information (user ID and email), provides a button to logout if the user is logged in and a login button if the user is not logged in. Create a profile.html file and add the following code:

<!DOCTYPE html> <html> <head> <title>Corbado</title> <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> <h1>Profile Page</h1> <div> <p id="info"></p> <button id="auth-button"></button> </div> </div> <script type="module"> await Corbado.load({ projectId: "pro-2796694128247001826", }) const createButton = (text, clickHandler) => { const buttonElement = document.getElementById('auth-button'); buttonElement.innerHTML = text; buttonElement.onclick = clickHandler; return buttonElement; } const addLoginButton = () => { return createButton('Login', () => { window.location.href = '/index.html'; }) } const addLogoutButton = () => { return createButton('Logout', async () => { await Corbado.logout(); window.location.href = '/index.html'; }) } if (!Corbado.user) { // User is not authenticated document.getElementById('info').innerHTML = `This content is only available to logged in users. You can log in here:` addLoginButton(); } else { // User is authenticated document.getElementById('info').innerHTML = ` User-ID: ${Corbado.user.sub} <br/> Email: ${Corbado.user.email} `; addLogoutButton(); } </script> </body> </html>

The file checks for the existence of the Corbado.user object. If this object exists, we know that the user is logged in and have access to the user information. If the user is not logged in, a hint to log in is shown. All that is handeld by Corbados session management internally, so we dont have to worry about sessions, cookies or tokens.

6. Start Using Passkeys with Our JavaScript Implementation

To start our application, we need a simple webserver which runs locally on our machine. We chose http-server for this task. Install it with

npm install --global http-server

Afterwards, enter the directory which contains the HTML files and start the web server by typing

http-server ./

When visiting http://localhost:8080 you should see the screen below. It's important to note that you should really visit http://localhost:8080 and NOT http://127.0.0.1:8080 or http://192.168.178.85:8080 (or any of the other local IP addresses in the console), as this would break with passkeys' property to have a relying party ID that matches the current domain.

Vanilla JavaScript Passkeys Sign up Page

After successful sign up / login, you see the profile page:

Vanilla JavaScript Passkeys Profile Page

7. Conclusion

This tutorial showed how easy it is to add passwordless authentication with passkeys to a plain HTML / JavaScript app using Corbado's Vanilla JavaScript component. 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 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