Skip to main content

Challenging users

Challenging users based on actions

An action is an event that a user performs in your application. For example, this could be a user signing in or updating their password. Authsignal allows you to record these actions through our track API. For each action, you can then define a set of rules that will determine whether the user should be required to complete a reauthentication challenge before proceeding.

How to track an action

To track an action, we recommend using one of our server-side SDKs. You can also use our Server API directly.

A common use case is tracking an action when a user signs in. In code, this would look like:

const result = await authsignal.track({
userId: user.id,
action: "signIn",
redirectUrl: "https://yourapp.com/callback", // Only required when using Authsignal's pre-built UI
});

const url = result.url;

The action response

When you track an action, Authsignal will return an action response. Some of the key fields are highlighted below:

state

The state field indicates the status of the action. It can be one of the following values:

  • CHALLENGE_REQUIRED: The action is pending. This means that applied rules have determined the user must complete a challenge before proceeding.
  • ALLOW: The rules have determined the user can proceed without a challenge.
  • BLOCK: The rules have determined the user cannot proceed with the action. This is a terminal state.

If we take the earlier code snippet as a starting point we can extend it to see how we could use the state field to perform our business logic:

const result = await authsignal.track({
userId: user.id,
action: "signIn",
redirectUrl: "https://yourapp.com/callback",
});

if (result.state === "CHALLENGE_REQUIRED") {
// Take the user to Authsignal pre-built challenge UI
res.redirect(result.url);
} else if (result.state === "ALLOW") {
// Allow the user to sign in
} else if (result.state === "BLOCK") {
// Block the user from signing in
}

url

The url field contains the URL of the Authsignal pre-built UI. In the above example, we redirect the user to this URL when the state is CHALLENGE_REQUIRED. Once the user has been taken to the pre-built UI they will be required to complete a challenge before they can proceed with the action.

If the user completes the challenge successfully (or exits the challenge UI), they will be redirected to the redirectUrl that was provided when the action was tracked.

token

If you're not using Authsignal's pre-built UI and are building your own UI, you can pass this token to a Client SDK or use it to authenticate to the Client API.

Configuring your action

By default, all actions will be in an ALLOW state. This means that no challenges will be required for the action to proceed. In our sign in example, we want our users to always complete a challenge before proceeding. To do this, we need to configure our signIn action in the Authsignal Portal.

If you have already started tracking your signIn action you should see it listed in the Actions section of the portal like the following:

Otherwise, you can configure a new action by clicking the Configure a new action button and naming it signIn.

Once you are viewing your signIn action configuration, go to the Rules tab. Here you can change the default action outcome from ALLOW to CHALLENGE using the dropdown.

tip

Make sure you click the Save button to save your changes.

Validating an action challenge

It is important that you validate the result of a challenge on your server.

If using Authsignal's pre-built UI, a token search parameter will be appended to your redirectUrl when redirecting back to your application. Or if you're building your own UI and using one of our Client SDKs, you should send the result token returned by the client SDK to your server.

For example:

const { state } = await authsignal.validateChallenge({ token });

if (state === "CHALLENGE_SUCCEEDED") {
// The user completed the challenge successfully
// Proceed with authenticated action or integrate with IdP to create authenticated session
} else {
// The user did not complete the challenge successfully
}

Next steps

In this example, we have configured our signIn action to always require a challenge. However, we may find that our users are being challenged too frequently. In the next section, we will learn how to configure our action with a rule so that our users only get challenged in high-risk scenarios.