If you're looking to enhance your Solid.js app's authentication by adding passkeys, you're in the right place! In this tutorial, we'll guide you through the process of integrating passkey authentication into your existing Solid app.
We'll assume that you already have an authentication system in place, so we'll focus specifically on adding a passkey functionality to complement your current setup.
To bring passkeys to your app, you'll typically need two things:
So, let's get started on upgrading your app's login experience! To make it easier for you to follow along, we have created a sample app that you can use as a reference throughout the tutorial.
We'll be implementing passkeys in two phases.
This is what the general flow looks like. There will be two steps ("start" and "finalize"), which pass through the frontend, backend, and Passkey API.
1. Start Registration: Client requests server to start registration, server fetches creationOptions
from Passkey API, and passes them to the client.
2. Create Credential: Client creates the passkey using creationOptions
.
3. Finalize Registration: Client sends credential to server, server validates it with Passkey API, and confirms registration to client.
Let's implement it in the code:
Make sure you have the passkey SDK installed in your backend.
Start by creating two functions, startServerPasskeyRegistration
and finishServerPasskeyRegistration
 which will be used in the /passkeys/register
route in the next step.
Let's breakdown the above code step by step:
Step 1: Import the necessary dependencies
tenant
function from the @teamhanko/passkeys-sdk
package to initialize the Passkey API.Step 2: Initialize the Passkey API
tenant
function and providing the required configuration, such as the API key and tenant ID.Step 3: Implement the startServerPasskeyRegistration
function
userID
as a parameter and initiates the passkey registration process.db.users
array based on the provided userID
.passkeyApi.registration.initialize
method, passing the user's ID and email as options.createOptions
object received from the Passkey API.Step 4: Implement the finishServerPasskeyRegistration
function
credential
object as a parameter and finalizes the passkey registration process.passkeyApi.registration.finalize
method, passing the credential
object.Now, set up the API endpoint for passkey registration:
/passkeys/register
method. The checkAuth
middleware is used to ensure the user is authenticated.c.get('user').id
. If the user ID is not available, we return an "Unauthorized" error response.start
, finish
, and credential
properties from the request body using c.req.json()
.start
property is present, find the user in the db.users
array based on the authenticated user's ID. startServerPasskeyRegistration
function with the user's ID to initiate the passkey registration process and obtain the createOptions
.createOptions
in the response.finish
property is present, we call the finishServerPasskeyRegistration
function with the provided credential
to complete the passkey registration.This API endpoint allows client to initiate and complete the passkey registration.
Install the @github/webauthn-json
library in your Solid.js frontend.
Next, create a registerPasskey
function which will be called when the user clicks a button to register a new passkey. It handles the client-side process of registering a passkey.
The function starts by sending a POST request to the server at the endpoint /passkeys/register
to initiate the passkey registration process. The request includes a JSON payload with the following properties:
start: true
: Indicates that the registration process is starting.finish: false
: Indicates that the registration process is not yet finished.credential: null
: Initially, no credential is provided.The function then awaits the response from the server and extracts the createOptions
from the response JSON.
Next, the function calls the create
function from @github/webauthn-json
library, passing the createOptions
as an argument.
After obtaining the credential
, the function sends another POST request to the same endpoint, but this time with a different payload:
start: false
: Indicates that the registration process is no longer starting.finish: true
: Indicates that the registration process is finished.credential
: The newly created passkey credential.Finally, if the response is successful, a passkey is registered for the user.
Now, to make it work we're missing one crucial step: getting the Tenant ID
and API key secret
from Hanko Cloud. For that, navigate over to Hanko, create an account, and set up your organization. Navigate to 'Create new project', select 'Passkey Infrastructure', and provide your project name and URL.
Note: It's recommended to create separate projects for your development and production environments. This way, you can use your frontend localhost URL for the development project and your production URL for the live project, ensuring a smooth transition between environments without the need to modify the 'App URL' later.
Obtain your Tenant ID
and create an API key, then add the Tenant ID
and API key secret
to your backend's '.env' file.
Now that you have your secrets added to your backend's .env
file, you should be all set to register a passkey. Go ahead and give it a try!
Implementing passkey login will be pretty similar to passkey registration. Create two more functions startServerPasskeyLogin
 and finishServerPasskeyLogin
 to start and finalize the login process.
These will be used in the /passkeys/login
route below.
/passkeys/register
, Â /passkeys/login
POST route is defined.start
, finish
, and options
properties from the request body using c.req.json()
.start
property is present, we call the startServerPasskeyLogin
function to initiate the passkey login process and obtain the loginOptions
.loginOptions
in the response.finish
property is present, we call the finishServerPasskeyLogin
function with the provided options
to complete the passkey login and obtain a JWT token which the Hanko Passkey API returns.Now we create a signInWithPasskey
function. This function will interact with the backend APIs to login the user with their registered passkeys.
Thats it! You now have a fully functional passkey login in your Solid.js app, significantly enhancing the user experience and making the authentication process more seamless for your users 🚀
You can always reach out to us on Discord if you run into any issues.