Using the pre-built UI

The Authsignal pre-built UI can be used to let users enroll methods for passwordless authentication or MFA.

Generating an enrollment URL

The integration steps for enrolling users via a pre-built UI URL are very similar to the integration steps for challenging users who are already enrolled.

First, we track an action in our server-side code to generate a short-lived pre-built UI URL.

const request = {
  userId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
  action: "enroll",
  attributes: {
    redirectUrl: "https://yourapp.com/callback",
  },
};

const response = await authsignal.track(request);

const url = response.url;

Once we have obtained this URL, we can use it to launch the pre-built UI and let the user enroll their first authenticator.

Launching the pre-built UI to enroll users with email OTP

Enrolling more authenticators

Users can enroll additional methods through the pre-built UI by first completing a challenge with one of their existing methods.

We can add the redirectToSettings attribute to the track request to land the user on a screen after their challenge which will let them enroll more methods.

const request = {
  userId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
  action: "manageAuthenticators",
  attributes: {
    redirectUrl: "https://yourapp.com/callback"
    redirectToSettings: true,
  },
};

const response = await authsignal.track(request);

const url = response.url;

If a user has previously enrolled email OTP, for example, then they can complete an email OTP challenge in order to enroll passkey as another authentication option.

Enrolling a passkey after completing an email OTP challenge

This requirement to authenticate with an existing method in order to add new methods ensures a strong binding between a user’s different authenticators.

If you want to display different button text to launch the pre-built UI based on whether the user is enrolled or not, as in the above example, you can query this via the Get User or Get Authenticators methods.

Enrolling email and SMS authenticators

By default Authsignal’s pre-built UI requires users to enter their email address or phone number when enrolling an email or SMS-based authenticator.

Capturing a user's email address to enroll an OTP authenticator

If you’ve already captured the user’s email in your own system, however, then you can skip this step by passing the user’s email or phone number in the track request.

const request = {
  userId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
  action: "enroll",
  attributes: {
    redirectUrl: "https://yourapp.com/callback",
    email: "jane@authsignal.com",
  },
};

const response = await authsignal.track(request);

This will skip the email or phone number input step during enrollment, but still allow the user to edit the value later. If you wish to prevent the user from editing the value, this can be configured in the Authsignal Portal by disabling the self-service management setting on the relevant authenticator configuration.

Additionally, if you’re already verified the user’s email in your own system then you can programmatically enroll them with an email or SMS authenticator at an appropriate point in your app (e.g. during a registration flow).

Using Client SDKs

You can also use Authsignal’s Client SDKs to enroll authenticators. This approach is recommended if you’re implementing Authsignal in a native mobile app or if you need to craft your own custom web UI.

Generating an enrollment token

To securely enroll a new authentication method via a Client SDK, first we track an action from our server-side code using a Server SDK or the Server API.

const request = {
  userId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
  action: "enroll",
};

const response = await authsignal.track(request);

const token = response.token;

From this we can obtain a token and pass it to the Client SDK in our app code to enroll an authentication method such as email OTP.

authsignal.setToken("eyJhbGciOiJ...");

// Send the user an email OTP code
// You can call this multiple times via a 'resend' button
await authsignal.email.enroll({ email: "jane@authsignal.com" });

// Verify the inputted code matches the original code
const response = await authsignal.email.verify({ code: "123456" });

Enrolling more authenticators

You can also use Client SDKs to enroll additional authenticators once a user is already enrolled.

const request = {
  userId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
  action: "enroll",
  attributes: {
    scope: "add:authenticators",
  },
};

const response = await authsignal.track(request);

const token = response.token;

The scope “add:authenticators” means that the token will be valid to enroll more authenticators for a user who is already enrolled.

To learn more about how to securely enroll multiple authenticators using Client SDKs, refer to our documentation on authenticator binding.

This token can be passed to a Client SDK to allow users to enroll another authentication method such as a passkey.

const { data: resultToken, error } = await authsignal.passkey.signUp({ 
  token,
  userName,
  displayName,
});

Next steps