You can add two-factor authentication to your Bubble app by combining a TOTP plugin with backend workflows that generate secrets, create QR codes, and verify six-digit codes at login. This tutorial covers the full enable, verify, and recover cycle so your users get real security without leaving the Bubble editor.
Overview: Two-Factor Authentication in Bubble
This tutorial walks you through building a complete two-factor authentication system in Bubble. You will create the data structure to store 2FA secrets, build the enrollment flow where users scan a QR code, add a verification step to your login workflow, and provide recovery codes for users who lose access to their authenticator app. This guide is for Bubble builders who already have a working login system and want to add an extra layer of security.
Prerequisites
- A Bubble app with a working user registration and login system
- Basic familiarity with Bubble workflows and the Data tab
- The Toolbox plugin installed (for JavaScript actions)
- A TOTP plugin from the Bubble plugin marketplace (e.g., 2FA TOTP Generator)
Step-by-step guide
Set up the Data Types for 2FA
Set up the Data Types for 2FA
Go to the Data tab and open your User Data Type. Add these new fields: totp_secret (type: text) to store the user's unique TOTP secret, two_factor_enabled (type: yes/no, default: no) to track whether 2FA is active, and recovery_codes (type: text, list: yes) to store one-time recovery codes. These fields will power your entire 2FA system.
Pro tip: Set Privacy Rules on the totp_secret and recovery_codes fields so they are never visible to other users — only the Current User should be able to read their own 2FA data.
Expected result: Your User Data Type now has three new fields: totp_secret, two_factor_enabled, and recovery_codes.
Install and configure the TOTP plugin
Install and configure the TOTP plugin
Go to the Plugins tab and click Add plugins. Search for a TOTP plugin such as 2FA TOTP Generator or a similar plugin that supports generating secrets and verifying codes. Install it. Once installed, you will see new workflow actions available under Plugins in the workflow editor. The plugin typically provides: Generate Secret, Generate QR Code URL, and Verify Token actions.
Expected result: The TOTP plugin is installed and its actions appear in the workflow Plugins section.
Build the 2FA enrollment page
Build the 2FA enrollment page
Create a new page or add a section to your settings page. Add a Button element labeled Enable Two-Factor Authentication. In its workflow, add these actions in order: (1) Use the plugin's Generate Secret action to create a TOTP secret. (2) Use Make Changes to Current User to save the secret in the totp_secret field. (3) Use the plugin's Generate QR Code URL action, passing the secret and the user's email. (4) Display the QR code URL in an Image element using dynamic data. (5) Show a Text Input where the user enters the 6-digit code from their authenticator app to confirm setup.
Pro tip: Display the secret as plain text alongside the QR code so users can manually enter it if scanning fails.
Expected result: Users see a QR code they can scan with Google Authenticator or Authy, and a text input to confirm the code.
Verify the code and activate 2FA
Verify the code and activate 2FA
Add a Confirm button below the verification input. In its workflow, use the plugin's Verify Token action, passing the user's totp_secret and the code they entered. Add an Only When condition: only proceed if the verification returns true. If valid, use Make Changes to Current User to set two_factor_enabled to yes. Also generate 8-10 random recovery codes using the Generate Random String action from the Toolbox plugin, and save them in the recovery_codes field. Display the recovery codes and instruct the user to save them somewhere safe.
Expected result: After entering a valid code, the user's 2FA is activated and they receive a set of recovery codes.
Add a 2FA verification step to login
Add a 2FA verification step to login
Modify your login workflow. After the Log the user in action, add a condition: if Current User's two_factor_enabled is yes, do NOT navigate to the dashboard. Instead, navigate to a 2FA verification page. On that page, add a Text Input for the 6-digit code and a Verify button. The button's workflow should use the Verify Token action with Current User's totp_secret. If valid, navigate to the dashboard. If invalid, show an alert saying the code is incorrect.
Pro tip: Add a link on the 2FA verification page for users who lost their device — this should accept a recovery code instead.
Expected result: Users with 2FA enabled must enter a valid authenticator code after their password before reaching the dashboard.
Build the recovery code fallback
Build the recovery code fallback
On the 2FA verification page, add a link labeled Lost your device? that reveals a Text Input for recovery codes. When the user submits a recovery code, add a workflow that checks if the entered code exists in Current User's recovery_codes list (use the contains operator). If it does, remove that code from the list using Make Changes to Current User and the minus item operator, then redirect to the dashboard. This ensures each recovery code works only once.
Expected result: Users who lost their authenticator device can use a one-time recovery code to log in, and that code is immediately invalidated.
Complete working example
12FA WORKFLOW SUMMARY2====================34DATA STRUCTURE:5 User Data Type additions:6 - totp_secret (text)7 - two_factor_enabled (yes/no, default: no)8 - recovery_codes (text, list)910ENROLLMENT WORKFLOW (Settings page → Enable 2FA button):11 1. Plugin: Generate TOTP Secret → save as custom state12 2. Make Changes to Current User: totp_secret = Result of Step 113 3. Plugin: Generate QR Code URL (secret, user email, app name)14 4. Display QR in Image element (source = Result of Step 3)15 5. User scans QR with authenticator app16 6. User enters 6-digit code in Input17 7. Plugin: Verify Token (secret, code) → if valid:18 a. Make Changes to Current User: two_factor_enabled = yes19 b. Generate 8 recovery codes (Toolbox: Generate Random String)20 c. Make Changes to Current User: recovery_codes = list of codes21 d. Display recovery codes to user2223LOGIN WORKFLOW (Login page → Login button):24 1. Log the user in (email + password)25 2. IF Current User's two_factor_enabled is yes:26 → Go to page: 2fa-verify27 3. ELSE:28 → Go to page: dashboard29302FA VERIFY WORKFLOW (2fa-verify page → Verify button):31 1. Plugin: Verify Token (Current User's totp_secret, Input value)32 2. Only when: Result is valid33 3. Go to page: dashboard34 4. If invalid: show Alert "Incorrect code"3536RECOVERY WORKFLOW (2fa-verify page → Use Recovery Code button):37 1. Only when: Current User's recovery_codes contains Input value38 2. Make Changes to Current User:39 recovery_codes remove item: Input value40 3. Go to page: dashboard41 4. If not found: show Alert "Invalid recovery code"Common mistakes when implementing two-factor authentication in Bubble.io: Step-by-Step Guide
Why it's a problem: Storing the TOTP secret without Privacy Rules
How to avoid: Add a Privacy Rule on the User type so that totp_secret and recovery_codes are only visible when Current User is This User
Why it's a problem: Not providing recovery codes
How to avoid: Always generate and display one-time recovery codes when 2FA is first enabled, and remind users to store them safely
Why it's a problem: Navigating to the dashboard before verifying the 2FA code
How to avoid: Route users with two_factor_enabled=yes to a separate 2FA verification page before they ever reach the dashboard
Why it's a problem: Not invalidating used recovery codes
How to avoid: Remove the used recovery code from the list immediately after a successful recovery login using the minus item operator
Best practices
- Set strict Privacy Rules on totp_secret and recovery_codes fields so only the owning user can read them
- Generate at least 8 recovery codes and display them only once during enrollment
- Add a Disable 2FA option in user settings that requires the current 6-digit code to confirm
- Log 2FA events (enabled, disabled, recovery used) in a separate AuditLog Data Type
- Show the TOTP secret as plain text alongside the QR code for manual entry fallback
- Test your entire 2FA flow with a real authenticator app before deploying to live
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm building a Bubble.io app and need to add two-factor authentication. I have a working login system. Can you walk me through the data structure, plugin setup, enrollment flow, login verification, and recovery code system I need to build?
Add two-factor authentication to my app. I need a TOTP-based 2FA system with QR code enrollment, a verification step at login, and recovery codes. Set up the Data Types and workflows for the full enable/verify/recover cycle.
Frequently asked questions
Which authenticator apps work with Bubble 2FA?
Any TOTP-compatible authenticator app works, including Google Authenticator, Authy, Microsoft Authenticator, and 1Password. They all use the same time-based one-time password standard.
Does 2FA cost extra Workload Units?
The 2FA verification itself is minimal — one database read for the secret and one plugin action to verify. It adds negligible WU cost per login.
Can I use SMS instead of an authenticator app?
Yes, but it requires a third-party SMS service like Twilio connected via the API Connector. TOTP-based 2FA using an authenticator app is more secure and does not incur per-message costs.
What happens if a user loses their phone and their recovery codes?
You will need an admin workflow to manually disable 2FA. Create a backend workflow that sets two_factor_enabled to no and clears the totp_secret, triggered by an admin after verifying the user's identity.
Can I make 2FA mandatory for all users?
Yes. Add a condition on your dashboard page: if Current User's two_factor_enabled is no, redirect to the 2FA enrollment page. This forces all users to set up 2FA before accessing the app.
Is this secure enough for a production app handling sensitive data?
TOTP-based 2FA significantly improves security, but for apps handling financial or health data, consider additional measures. RapidDev can help audit your security setup and implement enterprise-grade authentication flows.
Can I customize the QR code appearance?
The QR code is generated as a standard image URL. You can control its size via the Image element dimensions in Bubble, but the QR pattern itself follows the TOTP standard and cannot be styled.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation