To authenticate with WebAuthn using Streambird, you need to complete two essential steps: registration and authentication. Registration allows users to associate a WebAuthn device with their account, while authentication verifies their identity. To complete both steps, you must make two requests to Streambird. The first request returns the necessary components to communicate with the WebAuthn device, while the second request transmits the WebAuthn response back to Streambird for verification.

For seamless integration, use the webauthn-json library to convert the JSON request into the appropriate data types by decoding and unmarshalling the body. The library outputs marshalled JSON, which you can send back to Streambird for processing.

WebAuthn Setup

To use WebAuthn, there are two main steps: registration and authentication. Registration involves associating a WebAuthn device with a user, while authentication verifies their identity. For both steps, two requests must be made to Streambird.

The first request returns the necessary components for communicating with the WebAuthn device, while the second transmits the WebAuthn response back to Streambird for verification. To make integration easier, use the webauthn-json library to convert the JSON request into appropriate data types by decoding and unmarshalling the body. The library outputs marshalled JSON, which can be sent back to Streambird for processing.

Step 1: Creating a Streambird User for WebAuthn

If the user attempting to register is not yet associated with a Streambird user ID, you will need to create a new user using Streambird’s /v1/users/create endpoint. You can do this using a cURL request such as the following:

cURL
curl \
-X POST https://api.streambird.io/v1/auth/users/create \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"first_name":"John","last_name":"Smith","email":"sandbox@streambird.io","phone_number":"+14152222222","requires_verification":true}'

Step 2: Begin and Initate WebAuthn Registration

To authenticate with WebAuthn, you first need to register an authenticator. This will have to happen once per registration. Start by generating the request needed for webauthn-json’s create call. To do this, make a request to Streambird’s /v1/auth/webauthn/registrations/begin endpoint. You need two fields for the request: a Streambird user_id and the domain where the webauthn-json’s create call will be invoked, i.e. your login page’s domain. There’s one optional field, authenticator_type, which can be used to require a certain type of WebAuthn device, either platform (like a fingerprint reader) or cross-platform. If you omit this field, Streambird will assume the default platform type is acceptable.

cURL
curl \
 -X POST https://api.streambird.io/v1/auth/webauthn/registrations/begin \
 -H "Authorization: Bearer $API_KEY" \
 -H "Content-Type: application/json" \
 -d '{"domain":"localhost","user_id":"user_24wFP9pDa9YiMJLun94iKykoZs2"}'

Step 3: Use webauthn-json to sign a registration request

To use Streambird, utilize the field public_key_credential_creation_options from the response received from the /v1/auth/webauthn/registrations/begin endpoint within the browser, and call the create method of webauthn-json. Be sure to handle any potential errors that may occur during this process, such as the absence of available WebAuthn devices for registration. Upon successful completion of the WebAuthn call, stringify the response in JSON format and prepare for another call to Streambird.

import * as webauthnJson from '@github/webauthn-json';

// Step 2 was implemented by you in the previous step
const beginResponse = await beginWebauthnRegisterationRequest();
const credential = await webauthnJson.create({
    publicKey: beginResponse.public_key_credential_creation_options
});
// You will implement this in Step 4
await registerWebauthn({
    public_key_credential: credential
});

Step 4: Create WebAuthn Registration

In Step 3, we created a JSON object, which we will now use as the public_key_credential in our request to /v1/auth/webauthn/registrations/create using Streambird. After Streambird validates the credential, it will return the webauthn_credential_id if the registration is successful. With this registration, the user can now be authenticated using WebAuthn. To ensure the validity of the user’s registration, we recommend storing both the webauthn_credential_id and domain, which can be checked before calling /v1/auth/webauthn/authentication/begin for future logins.

curl \
 -X POST https://api.streambird.io/v1/auth/webauthn/registrations/create \
 -H "Authorization: Bearer $API_KEY" \
 -H "Content-Type: application/json" \
 -d '{"public_key_credential":{"type":"public-key","id":"Aex6qH_dUebV6v43lypXMBWzi8Okem5kik0iL9IYAX3ixRcBrCqIiJR3lhzK2rnAV0jY9IcWQe3sGEeP9vLm6J_lzs9JwRMpZ2pa8aT8db6YiQFeOg","rawId":"Aex6qH_dUebV6v43lypXMBWzi8Okem5kik0iL9IYAX3ixRcBrCqIiJR3lhzK2rnAV0jY9IcWQe3sGEeP9vLm6J_lzs9JwRMpZ2pa8aT8db6YiQFeOg","response":{"clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiczUtMXNsNjVHZGhpdmlXNFl6V3QzVEtIaVdwTkgtN1VFMFZOMVVjdlJBayIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6MTIzNCIsImNyb3NzT3JpZ2luIjpmYWxzZX0","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjZSZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NFYccF7K3OAAI1vMYKZIsLJfHwVQMAVQHseqh_3VHm1er-N5cqVzAVs4vDpHpuZIpNIi_SGAF94sUXAawqiIiUd5Ycytq5wFdI2PSHFkHt7BhHj_by5uif5c7PScETKWdqWvGk_HW-mIkBXjqlAQIDJiABIVgg0SIINWeg85kEAAbo7sc6VK3TlRcpnG-A773q6o2NQzkiWCBv_QKpoNh2O2tGyR6qtClGW7B2o10xYiBaWCbo-xdnpA"},"clientExtensionResults":{}},"user_id":"user_24wFP9pDa9YiMJLun94iKykoZs2"}'

Step 5: Begin Authentication

To initiate authentication, you will use webauthn-json’s get method to generate a request. This request is created by sending a request to /v1/auth/webauthn/authentication/begin and including two fields: the user_id of the user and the domain on which the WebAuthn call will be executed.

curl \
    -X POST https://api.streambird.io/v1/auth/webauthn/authentication/begin \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"domain":"localhost","user_id":"user_24wFP9pDa9YiMJLun94iKykoZs2"}'

Step 6: Calling webauthn-json’s Get Method

To use webauthn-json’s get method, access the public_key_credential_request_options field from the /v1/webauthn/registrations/begin response and utilize it in the browser. Take care to handle any errors that may occur during this process. Once webauthn-json’s get method has been successfully called use the JSON object for the API call to Streambird.

// Note that this code runs on the front-end (browser)
import * as webauthnJson from '@github/webauthn-json';

// Retrieve data for authentication (Step 5)
const beginAuthenticationResponse = await beginWebauthnAuthenticationRequest();

// Call webauthn-json's get method (Step 6)
const credential = await webauthnJson.get({
    publicKey: beginAuthenticationResponse.public_key_credential_request_options
});

// Initiate authentication (Step 7)
await authenticateWebauthn({
    public_key_credential: credential
});

Step 7: Verify the WebAuthn Authentication

After calling webauthn-json’s get method using the data obtained from calling /v1/auth/webauthn/authentication/begin, you can use the resulting JSON object as the public_key_credential field to initiate authentication by sending a request to /v1/auth/webauthn/authentication/verify through Streambird. If there are any issues with the provided credential, Streambird will respond with a 400 error. Otherwise, a 200 response indicates that the authentication was successful.

curl \
    -X POST https://api.streambird.io/v1/auth/webauthn/verify \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"public_key_credential":{"type":"public-key","id":"AfrWIdqBscVPZiKM2SufpRbnJoFKi-YO_PXT4AGROgkuLuxeMI_JtqGmjZNbjAr4poY2hrVNtIHpKEg0_n4wonWzqxUL1gXS5KF9BgSbOLYFbz5n07W2","rawId":"AfrWIdqBscVPZiKM2SufpRbnJoFKi-YO_PXT4AGROgkuLuxeMI_JtqGmjZNbjAr4poY2hrVNtIHpKEg0_n4wonWzqxUL1gXS5KF9BgSbOLYFbz5n07W2","response":{"clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiMG50bXhaWUEzOEJfMlJMUjdNTXlpeDk4RmVhd3BfVmRocUs0MVVHNFFpQSIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6MTIzNCIsImNyb3NzT3JpZ2luIjpmYWxzZX0","authenticatorData":"SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFYmcd8w","signature":"MEUCIHK7P7LOo8O-F9hyyNAziMJAB7mXrWanv1hjWb9LS5MfAiEApfIwc7uFVGW7dIvxJe1_YwR0_F6a_6GsxT7mCY9e2iU","userHandle":"dXNlcl8yNmw3ZGJmQVk1OWZ0ZWptbTZtM09UZjRvejE"},"clientExtensionResults":{}}}'

Congratulations, you’re all set!

Now that you have successfully integrated WebAuthn, you have all the necessary components to authenticate your users securely. If you have any feedback or suggestions regarding the integration, we would love to hear from you as we value your input.