WebAuthn frontend setup
How to register a passkey
- Get the settings for creating new credentials from server
- Clean up the settings. json converts byte[] to strings so you need to manually convert them to array buffers. Function
coerceToArrayBufferis in webauth-helpers.jsoptions.challenge = coerceToArrayBuffer(options.challenge); options.user.id = coerceToArrayBuffer(options.user.id); options.excludeCredentials = options.excludeCredentials.map((c) =>{ c.id = coerceToArrayBuffer(c.id); return c; }); - Create the credentials
let credentials = await navigator.credentials.create({ publicKey: options }) - Pull out arrays into own arrays, may be needed if data is too long
let attestationObject = new Uint8Array(newCredential.response.attestationObject); let clientDataJSON = new Uint8Array(newCredential.response.clientDataJSON); let rawId = new Uint8Array(newCredential.rawId); - Create object to be sent to server. Function
coerceToBase64Urlis in webauth-helpers.jsconst data = { id: newCredential.id, rawId: coerceToBase64Url(rawId), type: newCredential.type, extensions: newCredential.getClientExtensionResults(), response: { AttestationObject: coerceToBase64Url(attestationObject), clientDataJSON: coerceToBase64Url(clientDataJSON), transports: newCredential.response.getTransports() } }; - Send to server to be saved
How to verify a passkey
- Get the assertion settings from server
- Clean up the byte[]’s in the settings
options.challenge = coerceToArrayBuffer(options.challenge); options.allowCredentials = options.allowCredentials .map((c) =>{ c.id = coerceToArrayBuffer(c.id); return c; }); - Get credentials from passkey
var credentials = await navigator.credentials.get({publicKey: options}); - Pull out arrays into own arrays, may be needed if data is too long
let authData = new Uint8Array(credential.response.authenticatorData); let clientDataJSON = new Uint8Array(credential.response.clientDataJSON); let rawId = new Uint8Array(credential.rawId); let sig = new Uint8Array(credential.response.signature); - Create object to be sent to server
const data = { id: credential.id, rawId: coerceToBase64Url(rawId), type: credential.type, extensions: credential.getClientExtensionResults(), response: { authenticatorData: coerceToBase64Url(authData), clientDataJSON: coerceToBase64Url(clientDataJSON), signature: coerceToBase64Url(sig) } }; - Send to server to be verified