Sign a user in on a kiosk after the user scans a QR code with a phone.
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:
The kiosk shows a QR code. No user is signed in. This is an anonymous challenge.
The user scans the QR code with a phone.
The user identifies themselves and completes a challenge.
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.
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.
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.
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.
const result = await authsignal.track({ userId, action: "signIn", // Must be the action code from step 1 challengeId, // From the QR code redirectUrl: "https://kiosk.example.com/api/finish",});redirect(result.url); // The Authsignal pre-built UI
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.
const { isValid, userId } = await authsignal.validateChallenge({ action: "signIn", // Must be the action code from step 1 token,});
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.
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.
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.
const result = await authsignal.validateChallenge({ action: "signIn", // Must be the action code from step 1 token: accessToken,});if (result.isValid) { // Make the kiosk session for result.userId}
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.
Was this page helpful?
⌘I
Assistant
Responses are generated using AI and may contain mistakes.