Skip to main content
This guide tells you how to authenticate a user on a device with limited input capabilities. The user scans a QR code and completes an authentication challenge on their mobile phone. The flow has four steps:
  1. The kiosk shows a QR code. No user is signed in. This is an anonymous challenge.
  2. The user scans the QR code with a phone.
  3. The user identifies themselves and completes a challenge.
  4. The shared device receives the result and signs the user in.
This guide is not about QR code app verification. In that method, an enrolled mobile app scans the code and approves the request with a private key.

Terms

Sequence diagram

Before you start

You need these items:
  • A tenant with an active authentication method.
  • An action configuration. The action must challenge the user.
  • The tenant ID. The kiosk uses the tenant ID as a publishable key.
  • The tenant secret. Your backend uses the tenant secret.
  • A web page that you control. The phone opens this page. The page reads the challengeId query parameter.
The kiosk uses only the tenant ID. Never put the tenant secret on the kiosk.

Step 1 - Create the challenge on the kiosk

The kiosk creates an anonymous challenge. This endpoint needs no QR code authentication method configuration.
The response has two values:
string
The identifier of the anonymous challenge. Put this value in the QR code.
string
The secret that identifies the kiosk. Store this value on the kiosk. The kiosk sends it with each poll request.
The challenge expires after the token duration of your tenant. The default duration is 10 minutes. Create a new challenge before the old challenge expires to show a fresh code.

Step 2 - Show the QR code

Build the contents of the QR code. Put your own sign-in URL in the code. Add the challenge ID as a query parameter.
Use any QR code library to draw the image.
A kiosk screen with the heading Scan to sign in above a QR code

The kiosk shows the QR code while it waits for a user

Do not put the device code in the QR code. The device code is the secret that shows that the poll comes from the kiosk.

Step 3 - Complete the challenge on the phone

The phone opens your sign-in page. Your page reads the challengeId parameter, identifies the user, then sends the user to the Authsignal pre-built UI.
1

Identify the user

Ask the user for an identifier. This example asks for a user ID. You can also ask for an email address or a phone number and then read the user ID from your own user record.
A phone screen with the heading Verify it's you above an identifier field and a Continue button

The page on the phone collects an identifier before it tracks the action

2

Track the action from your backend

Send the challenge ID with the request.
The action code in the track request must be the same as the action code in step 1. If the action codes are different, the request fails with 404 not_found and the message Challenge not found.
3

Let the user complete the challenge

The pre-built UI challenges the user based on the methods they have enrolled and methods that are configured on the action.
4

Validate the token on your backend

The pre-built UI sends the user to your redirectUrl. The URL carries a token.
A phone screen with the heading All done and the text You're signed in on the kiosk

The phone confirms the result after the user completes the challenge

The kiosk receives the same result from its own poll. Step 4 tells you how.

Step 4 - Poll the result on the kiosk

The kiosk polls the anonymous challenge with the challenge ID and the device code from step 1.
The response gives the state of the flow. Poll about one time each second while the challenge is active. Stop the poll when isConsumed is true. Stop the poll if the challenge expires.
A kiosk screen with the heading Verifying on your phone above an obscured QR code and a spinner

The kiosk hides the code after a user claims the challenge

When the response gives isVerified, send the accessToken to your backend. Validate the token before you make the kiosk session.
A kiosk screen with the heading You're in and the text Signed in as demo-1e247861

The kiosk signs the user in after it validates the access token

The final result is single-use. Authsignal invalidates the anonymous challenge when it gives the consumed result. A later poll with the same challenge ID and device code fails.