⚠️ This example is outdated !
Head over to SDK Reference for the updated packages.
Initialize the Passkey Client
Begin by initializing the Turnkey SDK by passing in a config object containing:rpId: The Relying Party Identifier, which is the effective domain of your application.apiBaseUrl: The base URL of the Turnkey API:https://api.turnkey.comdefaultOrganizationId: Your parent organization ID, which you can find in the Turnkey dashboard.
What's the purpose of the rpId?
What's the purpose of the rpId?
The
rpId is used in WebAuthn to uniquely identify the server that the passkey is associated with. The rpId is typically the effective domain of the web application, which is the domain portion of the URL without any subdomains. For example, if your application is hosted at app.example.com, the rpId would typically be example.com. This ensures that credentials are scoped to the correct domain and cannot be used by other domains, enhancing security.- Next.js
- TypeScript
First, wrap your application with the Then, create a new file
TurnkeyProvider in your app/layout.tsx file:app/layout.tsx
app/add-passkey.tsx where we’ll implement the passkey functionality:app/add-passkey.tsx
Authenticate the User
Now that that the Passkey Client is initialized, we’ll call thelogin function which will prompt the user to authenticate with their passkey. Additionally, this function will set the current user in local storage upon successful authentication, which will be used later when creating an additional authenticator.
The user object which gets stored in local storage is defined as follows:
- Next.js
- TypeScript
app/add-passkey.tsx
Get the current user
Before creating a new passkey, we’ll get the current user. This function will retrieve the user from local storage, which was set after calling thelogin function. We’ll need the userId to create the authenticator in the final step.
- Next.js
- TypeScript
app/add-passkey.tsx
Create User Passkey
Now that you have authenticated the user, you can call thecreateUserPasskey function to create a new user passkey credential. Calling this method will prompt the user to create a passkey, which will be securely stored by their browser. This credential will be associated with the user’s account and used for future authentication. Once the credential is created, we’ll use it in the next step to create a new authenticator for the user.
The credential includes an encoded challenge and attestation. The encoded challenge ensures the request is fresh and legitimate, while the attestation verifies the authenticity of the device creating the credential. For more information on how passkeys work, including details on the challenge and attestation objects, you can refer to the Passkeys Documentation.
- Next.js
- TypeScript
app/add-passkey.tsx
Add the credential to the wallet
Now that you have created a new user passkey credential, we’ll use this credential to create a new passkey authenticator for the user. We’ll need the userId to create the authenticator, so we’ll get the current user first. This value comes from local storage which was set in the previous step when the user successfully authenticated via thelogin function.
- Next.js
- TypeScript
app/add-passkey.tsx
Complete add-passkey.tsx component
Complete add-passkey.tsx component
app/add-passkey.tsx
Optional: Read/Write Sessions
In some cases, you may want to create a read/write session for the user to reduce the number of passkey prompts. This session can be used instead of the passkey to sign requests to Turnkey’s API to improve the user experience. In the this tutorial we used the passkey to authenticate the request to create a new authenticator. The result is that the user will be prompted 3 times:- To login
- To create the new passkey
- To authenticate the request to create a new authenticator
- To login and create a session
- To authenticate the request to create a new authenticator
passkeyClient.login() with passkeyClient.loginWithReadwriteSession():
src/add-passkey.ts
- Next.js
- TypeScript
We’ll use the active client returned from the
useTurnkey hook which will be initialized with the read/write session. The rest of the code remains the same.app/add-passkey.tsx