Typescript library for next generation authentication.
Project website »
Documentation
·
Quick start
·
Demo
[!TIP]
Not using a Node backend? The examples in this README use our@passlock/nodeserver library, but this is not required. Passlock works similarly to Oauth2/OpenID Connect, so you can make vanilla HTTP calls or use any suitable JWT library to verify theid_token.
Passlock abstracts the complex and ever changing WebAuthn APIs into simple browser and server APIs. Sensible defaults are chosen, but can be overridden if required, giving you a powerful authentication toolkit.
:muscle: Powerful - We expose the full WebAuthn/Passkey featureset including user verification, autofil, backup/sync and more
:ok_hand: Headless components - Giving you 100% control over the UI
:toolbox: Framework agnostic - Passlock works with all major frontend & backend frameworks
:woman_technologist: Dev console - Something not working? check the unified client/server dev console
:desktop_computer: Management console - Suspend or revoke access for users, passkeys and more..
:male_detective: Audit trail - View a full audit trail for each passkey and user
This is a really basic introduction. Please check out the documentation for detailed explanations, examples and framework integration guides.
Passkey registration is a two step process. First you use this library to register a passkey on the users device, this generates a code and id_token (jwt) which you send to your backend. Your backend code then verifies the code or id_token and associates the passkey with a user.
// unsafe means the function can throw errors
import { registerPasskeyUnsafe } from "@passlock/client/passkey";
// get this from your dev tenancy settings in the Passlock console
const tenancyId = "myTenancyId";
// capture in a form or prefill if the user is already logged in
const username = "[email protected]";
// call this in a button click handler or similar action
// NOTE unsafe just means the function could throw an error
const result = await registerPasskeyUnsafe({ tenancyId, username });
// send this to your backend
console.log({ code: result.code, id_token: result.id_token });
Use the @passlock/node library to verify the new passkey:
// unsafe means the function can throw errors
import { exchangeCodeUnsafe } from "@passlock/node/principal";
// get these from your development tenancy settings
const tenancyId = "myTenancyId";
const apiKey = "myApiKey";
// get details about the new passkey
// NOTE unsafe just means the function could throw an error
const result = await exchangeCodeUnsafe(code, { tenancyId, apiKey });
// includes details about the new passkey
console.log(result);
// your function
await linkPasskey(userId, result.authenticatorId);
Passkey authentication is very similar to registration. You use the client library to authenticate a passkey in your frontend, then send the code and/or id_token to your backend. Your backend verifies the code/id_token and looks up the user based on the passkey id (authenticatorId).
import { authenticatePasskeyUnsafe } from "@passlock/client/passkey";
// get this from your dev tenancy settings in the Passlock console
const tenancyId = "myTenancyId";
// call this in a button click handler or similar action
// NOTE unsafe just means the function could throw an error
const result = await authenticatePasskeyUnsafe({ tenancyId });
// send this to your backend
console.log({ code: result.code, id_token: result.id_token });
Use the @passlock/node library to verify authentication:
import { exchangeCodeUnsafe } from "@passlock/node/principal";
// get these from your development tenancy settings
const tenancyId = "myTenancyId";
const apiKey = "myApiKey";
// get details about the new passkey
// NOTE unsafe just means the function could throw an error
const result = await exchangeCodeUnsafe(code, { tenancyId, apiKey });
// includes details about the new passkey
console.log(result);
// your function
const user = await lookupUser(result.authenticatorId);
Please see the tutorial and documentation