Adding strong authentication in JavaScript
PingOne JavaScript
The FIDO module offers a streamlined API for handling FIDO interactions.
It abstracts away the complexities of the underlying FIDO protocols, allowing you to quickly add strong authentication to your applications.
Step 1. Installing modules
To add FIDO to your JavaScript apps you need this module:
-
fido
The fido module for JavaScript is exported as a member of the @forgerock/davinci-client npm package.
To install the DaVinci client and member modules:
-
Install the DaVinci client into your JavaScript apps using
npm:Install the DaVinci clientnpm install @forgerock/davinci-client --save
Step 2. Initialize the FIDO client
You need to import the FIDO module into your project, and initialize both the DaVinci client, and the FIDO API:
-
In your JavaScript app, import the DaVinci client, and
fidomodule as named imports:Import the DaVinci clientimport { davinci, fido } from '@forgerock/davinci-client'; -
Initialize the DaVinci client, and
fidomodule:const davinciClient = await davinci({ config }); const fidoApi = fido();Learn more about initializing the DaVinci client in Configuring the DaVinci module.
Step 3. Registering FIDO authenticators
To register a FIDO authenticator, use the register() function. The function returns a promise with FidoRegistrationInputValue, which contains the correctly-formatted public key credential, or a GenericError:
if (collector.type === 'FidoRegistrationCollector') {
const credentialOptions = collector.output.config.publicKeyCredentialCreationOptions;
const publicKeyCredential = await fidoApi.register(credentialOptions);
if ('error' in publicKeyCredential) {
// Handle the error
}
// Update the FidoRegistrationCollector with the credential or error
const updater = davinciClient.update(collector);
updater(publicKeyCredential);
}
let nextStep = davinciClient.next();
Step 4. Authenticating using a FIDO authenticator
To authenticate using a registered FIDO authenticator, use the authenticate() function. The function returns a promise containing either FidoAuthenticationInputValue, which contains the assertion you can return to DaVinci, or GenericError:
if (collector.type === 'FidoAuthenticationCollector') {
const credentialOptions = collector.output.config.publicKeyCredentialRequestOptions;
const assertion = await fidoApi.authenticate(credentialOptions);
if ('error' in assertion) {
// Handle the error
}
// Update the FidoAuthenticationCollector with the credential or error
const updater = davinciClient.update(collector);
updater(assertion);
}
let nextStep = davinciClient.next();
Step 5. Handling FIDO client-side errors
If a call to register() or authenticate() fails, the returned promise resolves to a GenericError instead of a credential or assertion. That error object carries a code property, typed as FidoErrorCode, which normalizes the underlying WebAuthn DOMException into one of the following values:
-
NotAllowedError -
AbortError -
InvalidStateError -
NotSupportedError -
SecurityError -
TimeoutError -
UnknownError- Returned when the underlying error doesn’t match any of the recognized WebAuthn error names.
|
The FIDO module does not automatically submit a client-side error back to DaVinci. Reporting the error, and deciding when to progress the flow afterwards, is left to your app. |
To report a client-side error, call davinciClient.update(collector) with the error object, the same way you would with a successful credential or assertion, and then call next() when you’re ready to continue the flow:
const publicKeyCredential = await fidoApi.register(credentialOptions);
if ('error' in publicKeyCredential) {
console.error(publicKeyCredential.code, publicKeyCredential.message);
const updater = davinciClient.update(collector);
updater(publicKeyCredential); // Send the error’s `code` and `message` back to the flow
}
// Call `next()` when you’re ready to continue, for example after showing the user a message
let nextStep = davinciClient.next();
DaVinci flows can use the reported code to branch. For example, to offer a retry after a TimeoutError, or to fall back to another authentication method after a NotAllowedError.