Skip to content

Authenticate a passkey

The process is almost identical to passkey registration. You’ll use the Passlock client library to trigger passkey login on the device, then send the resulting code to your backend.

sequenceDiagram
  participant Frontend
  participant Client as Passlock Client
  participant Backend
  participant Server as Passlock Server

  Frontend->>Client: authenticatePasskey()
  Client-->>Frontend: id_token, code

  Frontend->>Backend: code

  Backend->>Server: exchangeCode(code)
  Server-->>Backend: authenticatorId
  
  Backend->>Backend: lookupUser(authenticatorId)

This time you don’t need a username. Passkeys are discoverable, meaning the browser/device will prompt the user to select the passkey they want to sign in with:

import {
authenticatePasskey,
isAuthenticationSuccess
} from "@passlock/client/passkey";
// get this from your development tenancy settings
const tenancyId = "myTenancyId";
// call this in a button click handler or similar action
const result = await authenticatePasskey({ tenancyId });
if (isAuthenticationSuccess(result)) {
// send this to your backend
console.log({ code: result.code });
} else {
console.error(result.message);
}

As before, submit the code to your backend.

The process is exactly the same as for the registration flow..

import { exchangeCode, isPrincipal } from "@passlock/node/principal";
// get these from your development tenancy settings
const tenancyId = "myTenancyId";
const apiKey = "myApiKey";
const result = await exchangeCode(code, { tenancyId, apiKey });
if (isPrincipal(result)) {
console.log(result);
} else {
console.error(result.message);
}

The Pricipal includes an authenticatorId, which you previously linked to a user account in your backend system. You’ll use this id to lookup the associated user and log them in.

If you’re unable to use the Passlock server library, you can make a simple REST call:

GET /{tenancyId}/principal/{code} HTTP/1.1
Host: https://api.passlock.dev
Accept: application/json
Authorization: Bearer {apiKey}