A QR code displayed on a desktop or kiosk device.

This method uses the Device SDK to sign a challenge with the user’s device credentials.

Using device auth with a QR code is useful in scenarios where users are authenticated on a mobile device with a long session, and need to authenticate on a separate device with short sessions or poor input capabilities.

Use cases

  • Log into a desktop or web application from an application that is typically used on mobile.
  • Identify a user on a kiosk in a quick service restaurant (QSR) to load loyalty programs, rewards and offers.
  • Log into an application running on a TV.
  • Complete a payment via a terminal.

Prerequisites

Sequence

Implementation

1. Present a QR code (Desktop / Kiosk / Terminal)

1.1. Request a QR code challenge (Frontend)

Use our browser SDK or API to initiate an anonymous QR code challenge. This is called an anonymous challenge because it is not associated with a user.

const response = await authsignal.qrCode.challenge({ action: "login-with-qr-code" });

1.2. Display the QR code (Frontend)

Using the challengeId returned from the challenge request, display the QR code using a library of your choice.

1.3. Poll for the challenge result (Frontend)

Poll for the challenge result using our browser SDK or API. We recommend polling every 1-2 seconds.

const response = await authsignal.qrCode.verify({
  challengeId: "challenge_id",
  deviceCode: "device_code",
});

Poll states:

1

Not claimed

The challenge has not been claimed by any users. Continue showing the QR code.

{
  "isClaimed": false,
  "isConsumed": false,
  "isVerified": false
}
2

Claimed

isClaimed is true

The challenge has been claimed by a user. Blur the QR code.

{
  "isClaimed": true,
  "isConsumed": false,
  "isVerified": false
}
3

Declined

isConsumed is true, isVerified is false

The challenge has been declined by a user. Show an error message to the user and provide a way to retry the challenge.

{
  "isClaimed": true,
  "isConsumed": true,
  "isVerified": false
}
4

Verified

isConsumed is true, isVerified is true and an accessToken is returned.

The challenge has been verified by a user. Show a success message to the user and proceed with the next step.

{
  "isClaimed": true,
  "isConsumed": true,
  "isVerified": true,
  "accessToken": "access_token"
}

2. Scan the QR code (Mobile App)

Once the user scans the QR code, use the mobile sdk claimChallenge method to set the user attempting to complete the challenge.

The claimChallenge method will return some context about the desktop or kiosk initiating the challenge such as ip address, location, user agent and custom data. This data can be shown to the user to help them decide if they want to approve or decline the challenge.

const response = await authsignal.device.claimChallenge({
  challengeId: "challenge_id",
});

3. Approve or decline the challenge (Mobile App)

Present a dialog to allow the user to review the challenge context and approve or decline the challenge by calling the mobile sdk updateChallenge method.

const response = await authsignal.device.updateChallenge({
  challengeId: "challenge_id",
  approve: true,
});

4. Validate the challenge (Backend)

Once the challenge is approved, the challenge verify api being polled in step 1.3 will return an accessToken that should be passed to your backend to validate the challenge prior to completing the authentication flow.

const request = {
  token: "eyJhbGciOiJ...",
};

const response = await authsignal.validateChallenge(request);

if (response.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
}

If the challenge is declined, the api will return isConsumed as true and isVerified as false. The UI should be updated to reflect that the challenge was declined.