Introduction
This document outlines the example usage of the HYPR FIDO2 Browser SDK so that you can do registration and authentication of users. This SDK provides an abstraction layer to simplify the FIDO2 WebAuthn APIs for simpler developer experience.
Getting the SDK
In order to get the SDK, ask your HYPR support representative for the FIDO2 Browser SDK. This will be a JavaScript file deliverable called hyprfido2sdk.js
The below code sample also has the entire SDK in a single line of minified javascript:
function base64ToArrayBuffer(r){let e=atob(r),n=e.length,t=new Uint8Array(n);for(let r=0;r<n;r++)t[r]=e.charCodeAt(r);return t.buffer}function bufferToString(r){return new Uint8Array(r).reduce((r,e)=>r+String.fromCodePoint(e),"")}function toBase64URL(r){return r=(r=(r=r.split("=")[0]).replace(/\+/g,"-")).replace(/\//g,"_")}function fromBase64URL(r){var e=(r=r.replace(/-/g,"+").replace(/_/g,"/")).length%4;if(e){if(1===e)throw new Error("InvalidLengthError: Input base64url string is the wrong length to determine padding");r+=new Array(5-e).join("=")}return r}
const HYPRFido2Client={createAttestationOptions:function(e,t,n="platform",a="required",r=!1,i="direct"){return{username:e,displayName:t,authenticatorSelection:{authenticatorAttachment:n,userVerification:a,requireResidentKey:r},attestation:i}},createAssertionOptions:function(e,t="preferred",n="platform"){return{username:e,userVerification:t,authenticatorSelection:{authenticatorAttachment:n}}},createFido2Credential:function(e,t,n=!0){function a(e){return{id:e.id,rawId:toBase64URL(btoa(bufferToString(e.rawId))),type:"public-key",response:{clientDataJSON:toBase64URL(btoa(bufferToString(e.response.clientDataJSON))),attestationObject:toBase64URL(btoa(bufferToString(e.response.attestationObject)))}}}if(HYPRFido2Client.checkWebAuthnSupport(t))"platform"===e.authenticatorSelection.authenticatorAttachment?PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().then(function(r){if(r)navigator.credentials.create(HYPRFido2Client.makePublicKey(e,n)).then(e=>{t(null,a(e))}).catch(e=>{console.error("Error processing credential create request for WebAuthn with code: "+e.code+" and message: "+e.message+" and name: "+e.name),t(e)});else{const e=new Error("Cannot continue since WebAuthn Platform Authentication is not available on this browser and client");e.name="WebAuthnPlatformUnavailable",t(e)}}).catch(e=>{console.error("Error processing credential create request for WebAuthn with code: "+e.code+" and message: "+e.message+" and name: "+e.name),t(e)}):navigator.credentials.create(HYPRFido2Client.makePublicKey(e)).then(e=>{t(null,a(e))}).catch(e=>{console.error("Error processing credential GET request for WebAuthn with code: "+e.code+" and message: "+e.message+" and name: "+e.name),t(e)});else{const e=new Error("Cannot continue since WebAuthn is not available on this browser and client");e.name="WebAuthnUnavailable",t(e)}},useFido2Credential:function(e,t){HYPRFido2Client.checkWebAuthnSupport(t)&&navigator.credentials.get({publicKey:{challenge:base64ToArrayBuffer(fromBase64URL(e.challenge)),timeout:e.timeout,rpId:e.rpId,userVerification:e.userVerification,allowCredentials:e.allowCredentials}}).then(e=>{let n={id:e.id,rawId:toBase64URL(btoa(bufferToString(e.rawId))),type:e.type,response:{authenticatorData:toBase64URL(btoa(bufferToString(e.response.authenticatorData))),clientDataJSON:toBase64URL(btoa(bufferToString(e.response.clientDataJSON))),signature:toBase64URL(btoa(bufferToString(e.response.signature))),userHandle:toBase64URL(btoa(bufferToString(e.response.userHandle)))}};t(null,n)}).catch(e=>{console.error("Error processing credential assertion request for WebAuthn with code: "+e.code+" and message: "+e.message+" and name: "+e.name),t(e)})},makePublicKey:function(e,t){return e.excludeCredentials&&(e.excludeCredentials=e.excludeCredentials.map(function(e){return e.id=base64ToArrayBuffer(fromBase64URL(e.id)),e.transports=["internal","usb","ble","nfc"],e})),t&&(e.excludeCredentials=[]),{publicKey:{attestation:e.attestation,authenticatorSelection:e.authenticatorSelection,excludeCredentials:e.excludeCredentials,rp:e.rp,user:{id:base64ToArrayBuffer(fromBase64URL(e.user.id)),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams,timeout:e.timeout,challenge:base64ToArrayBuffer(fromBase64URL(e.challenge))}}},isFido2Available(e,t=!0){if(HYPRFido2Client.checkWebAuthnSupport())t?PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().then(function(t){if(t)e(null,!0);else{const t=new Error("Cannot continue since WebAuthn Platform Authentication is not available on this browser and client");t.name="WebAuthnPlatformUnavailable",e(t,!1)}}):e(null,!0);else{const t=new Error("Cannot continue since WebAuthn is not available on this browser and client");t.name="WebAuthnUnavailable",e(t,!1)}},checkWebAuthnSupport:function(){return void 0===window.PublicKeyCredential||window.PublicKeyCredential,!0}};
SDK Function Overview
The SDK has 5 core functions that can be leveraged before and during registration as well as authentication.
HYPRFido2Client.isFido2Available
HYPRFido2Client.isFido2Available
This is the function that you should call to check if your browser supports FIDO2 in general. This check can be made before doing any of the other functions below to ensure an optimal user experience.
Parameter Name | Description | Default Value |
---|---|---|
| The callback that gets invoked as a result of this check. |
|
| Whether or not to check if a platform authenticator is available at the same time. Default value is true |
|
Example
let isFido2AvailableCallback = (error, result) => {
if (error !== null) {
console.log("(isFido2AvailableCallback Callback) There was an error: " + String(error));
return;
}
console.log("(isFido2AvailableCallback Callback) Got use credential result: " + result);
};
HYPRFido2Client.isFido2Available(isFido2AvailableCallback);
HYPRFido2Client.createAttestationOptions
HYPRFido2Client.createAttestationOptions
This is the function you should call to get the payload that you need to send to the FIDO2 server options endpoint for registration.
The function definition and parameters are described below:
Parameter Name | Description | Default Value |
---|---|---|
| The username of the user you'd like to register |
|
| The display name of the user you'd like to register |
|
| The authenticator attachment for this registration |
|
| The user verification type for this registration |
|
| Whether or not to use a resident key |
|
| The attestation type to use for registration |
|
Example
/**
* @returns {{attestation: *, displayName: *, authenticatorSelection: {authenticatorAttachment: *, userVerification: *, requireResidentKey: *}, username: *}}
*/
createAttestationOptions: function (username,
displayName,
authenticatorAttachment = "platform",
userVerification = "preferred",
isResidentKeyRequired = false,
attestationType = "direct");
HYPRFido2Client.createAssertionOptions
HYPRFido2Client.createAssertionOptions
This function should be called when you need to make an options request to your FIDO2 server for authentication.
The function definition and parameters are described below:
Parameter Name | Description | Default Value |
---|---|---|
| The username for this particular user |
|
| The user verification type |
|
| The authenticator attachment type |
|
Example
/**
* @returns {{userVerification: *, authenticatorSelection: {authenticatorAttachment: *}, username: *}}
*/
createAssertionOptions: function (username,
userVerification = "preferred",
authenticatorAttachment = "platform");
HYPRFido2Client.createFido2Credential
HYPRFido2Client.createFido2Credential
This function should be called when you are doing registration with FIDO2.
Parameter Name | Description | Default Value |
---|---|---|
| This is the options response from the attestation FIDO2 options request. |
|
| This is your callback function that will be invoked in the event of an error or successful completion. |
|
| Whether or not to remove the exclude credentials list from the server during the create request. *This will allow the user to register the same authenticator on the same computer multiple times |
|
Example
createFido2Credential: function (serverAttestationOptionsResponse, callback);
HYPRFido2Client.useFido2Credential
HYPRFido2Client.useFido2Credential
This function should be called when you are doing authentication with FIDO2
Parameter Name | Description |
---|---|
| This is the JSON response of your assertion options request to the FIDO2 server |
| This is your callback function that will be invoked in the event of an error or successful completion. |
Example
useFido2Credential: function (serverAssertionOptionsResponse, callback);
User Registration
Use the below steps to register a new user with your application.


Registration Flow Diagram
Step 1 - Create your options request
Get your registration options by calling the createAttestationOptions function. The below example uses the default argument values shown in the SDK function overview above except the username and display name.
Example
//Pass your arguments to the function
let attestationOptions = HYPRFido2Client.createAttestationOptions("[email protected]", "John Doe");
Step 2 - Get the registration options from the server
Make a REST API call to your FIDO2 server attestation options request (/attestation/options).
The payload that you pass in the POST request should be the attestationOptions you got in Step 1 above.
Developer Tip
HYPR provides a Postman collection with samples of the REST APIs for this step. This collection includes specific payload information that you can use. You can see the public APIs that are currently available here
Step 3 - Create the passwordless credential
Once you get a 200 response from the REST API call in Step 2, call the createFido2Credential function in the SDK to create your local credential.
In order to call this function, you'll need to define a callback that will be invoked in the event of an error or completion of the credential creation.
Example
let attestationCallback = (error, result) => {
if (error !== null) {
console.log("(Attestation Callback) There was an error: " + String(error));
return;
}
console.log("(Attestation Callback) Got create credential result: " + result);
};
HYPRFido2Client.createFido2Credential(responseFromStep2, attestationCallback);
Step 4 - Complete the registration
Once your callback in Step 3 is called and the credential is created, make a REST API POST request to the FIDO2 server attestation result (/attestation/result) endpoint. The body of the REST API call will be the result in your callback from Step 3.
Developer Tip
HYPR provides a Postman collection with samples of the REST APIs for this step. This collection includes specific payload information that you can use. You can see the public APIs that are currently available here
User Authentication
Use the steps below do to user authentications once they are already registered.


Authentication Flow
Step 1 - Create your options request
Create the authentication options that you'll need to provide to the server by calling the createAssertionOptions function on the SDK. The only required parameter here is the username and in the example below, we use the default parameters for user verification and attachment.
Example
let authnOptions = HYPRFido2Client.createAssertionOptions("[email protected]");
Step 2 - Get the authentication options from the server
Once you get your authentication options from Step 1 above, you need to make a REST API POST request to the assertion options (/assertion/options) endpoint on your FIDO2 server.
The payload in this POST request should be the authnOptions that you got in Step 1.
Developer Tip
HYPR provides a Postman collection with samples of the REST APIs for this step. This collection includes specific payload information that you can use. You can see the public APIs that are currently available here
Step 3 - Use the stored credential
Once you get a successful response from your FIDO2 API in Step 2, you need to leverage the SDK to use the previously registered credential.
The useFido2Credential function will take in the response from Step 2 and a callback as parameters. This callback will be invoked by the SDK in the event of a successful use of the credential or in the event of an error.
Example
let assertionCallback = (error, result) => {
if (error !== null) {
console.log("(Assertion Callback) There was an error: " + String(error));
return;
}
console.log("(Assertion Callback) Got use credential result: " + result);
};
HYPRFido2Client.useFido2Credential(resp, assertionCallback);
Step 4 - Complete the authentication
Once your callback in Step 3 is called and the credential is successfully used, make a REST API POST request to the FIDO2 server assertion result (/assertion/result) endpoint. The body of the REST API call will be the result in your callback from Step 3.
Developer Tip
HYPR provides a Postman collection with samples of the REST APIs for this step. This collection includes specific payload information that you can use. You can see the public APIs that are currently available here
Error Handling
The below section highlights common errors that can occur when using the SDK and suggestions on how they should be handled.
name: WebAuthnUnavailable
Message: Cannot continue since WebAuthn is not available on this browser and client
Explanation: This error will occur if you try to register or authenticate a user but the browser the user is on doesn't support FIDO2 WebAuthn APIs.
If you encounter this error, then you should provide the user with an alternative method for authentication or registration such as a Push to mobile capability.
name: WebAuthnPlatformUnavailable
Message: Cannot continue since WebAuthn Platform Authentication is not available on this browser and client
Explanation: If you encounter this error, it means that your authenticator attachment during registration was "platform" and the computer that the user is on, doesn't support platform authenticators in the WebAuthn APIs.
If you encounter this error, give the user an alternative authenticator to register such as a mobile device or SmartKey device by leveraging the "cross-platform" authenticator attachment in your createAttestationOptions request.
name: InvalidStateError
Message: The user attempted to register an authenticator that contains one of the credentials already registered with the relying party
Explanation: If you encounter this error, it means that the username provided is already registered on this particular computer with the same authenticator that they selected.
If you feel that this is a mistake, you can try deleting the authenticator on the FIDO2 server by using the proper REST API call (see Postman collection for more details).
If you would like to register the same username multiple times on the same computer, you can do so by removing the "excludeCredentials" array from the server response in Registration Step 2 above.
name: NotAllowedError
Message: The operation either timed out or was not allowed.
Explanation: If you encounter this error, it can mean one of these items:
- The username you're trying to authenticate doesn't have any credentials registered on this computer. This can happen if they never registered or if they removed the credential from their computer or device.
If the user is not registered on this machine, then you should register them first.
The user cancelled the authentication or registration prompt that was given to them by the browser.
The user didn't complete the request within 30 seconds and their authentication or registration request timed out. In this case, you can try authenticating or registering the user again.
name: NotSupportedError
Message: Either the device has received unexpected request parameters, or the device cannot support this request.
Explanation: If you see this error, it most likely means that you are trying to register a device with the resident key value set to true in the create credentials request.
To overcome the issue, you should set the isResidentKeyRequired parameter to false when creating the FIDO credential.
Updated 10 months ago