How to Set up TOTP (Time-Based One-Time Passcodes)

Time-based one-time passcodes (TOTP) offer a passwordless, two-factor authentication option that provides a high level of security for sensitive use cases. TOTP authentication is particularly well-suited for scenarios like fintech or cryptocurrency transactions.

When integrated as a second factor, TOTP requires users to prove device possession by generating a unique one-time passcode based on the current time and a shared secret between the authenticator app (e.g. Google Authenticator or Authy) and the server (Streambird API). To use TOTP, users must have an authenticator app installed on their device and input the unique passcode within a specified time window, usually 30 seconds, as evidence of their identity.

Once the user inputs the TOTP code, your app can use Streambird /v1/auth/totps/verify endpoint to verify the code’s validity and grant access. TOTP authentication is a reliable way to enhance security for critical services that require a high level of protection, without relying on passwords.

Step 1: Create a user account with the Streambird API

If the user attempting to register isn’t already associated with a Streambird user_id, you’ll need to create a Streambird User with the /v1/auth/users/create endpoint. Pass any supported identifier, such as an email address, phone number, into the User create endpoint and store the returned user_id. The user_id will be used to register and authenticate with TOTP.

cURL
curl \
  -X POST https://api.streambird.io/v1/auth/users/create \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"first_name":"John","last_name":"Smith","email":"sandbox@streambird.io","phone_number":"+14152222222","requires_verification":true}'

This will return a JSON object containing the user ID.

Step 2: Create TOTP Instance for User

Replace user_26l7dbfAY59ftejmm6m3OTf4oz1 with the user ID obtained in the previous step. This will return a JSON object containing the TOTP ID, secret, recovery codes, and QR code image in base64 format.

  1. Store the TOTP secret and recovery codes in a secure location. The TOTP secret is a string of characters that should be kept secret, and the recovery codes are backup codes that can be used in case the TOTP device is lost or stolen.
  2. Display the QR code image to the user. This can be done by decoding the base64-encoded image data and displaying the resulting image. Many libraries are available for decoding base64 and displaying images in different programming languages.
  3. Ask the user to scan the QR code with a TOTP app on their mobile device, such as Google Authenticator or Authy. Alternatively, they can manually enter the TOTP secret into the app.
cURL
curl \
  -X POST https://api.streambird.io/v1/auth/totps/create \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id":"user_26l7dbfAY59ftejmm6m3OTf4oz1"}'

Step 3: Verify TOTP Code

To ensure that the TOTP instance does not expire, it is important that the user authenticates their first TOTP immediately after creating it. When the user submits the TOTP code, you will need to authenticate it by making a request to the /v1/auth/totps/verify endpoint and providing the user’s user_id along with the supplied totp.

To accommodate for network and user action delays, the /v1/auth/totps/verify endpoint accepts TOTP codes from the previous and next 30-second periods. This provides some flexibility and reduces the risk of failed authentication attempts due to timing issues.

If you need to begin a new Streambird session or re-use an existing one, you can pass in either the session_expires_in parameter to start a new session, or the session_token parameter to re-use an existing one. To learn more about managing user sessions, you can consult our comprehensive guide on session management.

cURL
curl \
 -X POST https://api.streambird.io/v1/auth/totps/verify \
 -H "Authorization: Bearer $API_KEY" \
 -H "Content-Type: application/json" \
 -d '{"user_id":"user_26l7dbfAY59ftejmm6m3OTf4oz1","totp":"505361","session_expires_in":100}'