Authentication follows a four-step process:
- Request Challenge: The server generates and stores a random challenge.
- Trigger Authentication (Browser): Call
client.authenticate(credentialIds, challenge, options). If credentialIds is an empty array [], the platform will show a default UI to select a user (Passkeys/Discoverable credentials). - Load Credential (Server): The server retrieves the stored
credentialKey (id, publicKey, algorithm, synced) from the database using the credentialId provided in the authentication payload. - Verify Authentication (Server): Call
server.verifyAuthentication(authentication, credentialKey, expected) where expected includes challenge, origin, and optionally userVerified and counter.
// 1. Browser: Trigger authentication
import { client } from '@passwordless-id/webauthn'
const challenge = "56535b13-5d93-4194-a282-f234c1c24500"
const authentication = await client.authenticate(["3924HhJdJMy_svnUowT8eoXrOOO6NLP8SK85q2RPxdU"], challenge, {
authenticatorType: "auto",
userVerification: "required",
timeout: 60000
})
// 2. Server: Verify authentication
import { server } from '@passwordless-id/webauthn'
const credentialKey = {
id: "3924HhJdJMy_svnUowT8eoXrOOO6NLP8SK85q2RPxdU",
publicKey: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgyYqQmUAmDn9J7dR5xl-HlyAA0R2XV5sgQRnSGXbLt_xCrEdD1IVvvkyTmRD16y9p3C2O4PTZ0OF_ZYD2JgTVA==",
algorithm: "ES256",
synced: true
}
const expected = {
challenge: "56535b13-5d93-4194-a282-f234c1c24500",
origin: "http://localhost:8080",
userVerified: true,
counter: 123
}
const authenticationParsed = await server.verifyAuthentication(authentication, credentialKey, expected)