You can add Google Authenticator-based two-factor authentication to your Bubble app by generating TOTP secrets, displaying QR codes for the authenticator app, and verifying six-digit codes at login. This requires a TOTP plugin or API service to generate secrets and validate codes. The result is a secure 2FA flow that protects user accounts beyond just passwords.
Add Google Authenticator Two-Factor Authentication to Your Bubble App
This tutorial guides you through implementing TOTP-based two-factor authentication using Google Authenticator in your Bubble app. You will learn how to generate secrets, display QR codes, verify codes during login, and provide recovery options. This is essential for apps handling sensitive data, financial transactions, or user accounts that need extra security.
Prerequisites
- A Bubble account with an existing app that has user authentication (login/signup)
- Basic understanding of Bubble workflows and the Data tab
- A smartphone with Google Authenticator (or any TOTP app) installed for testing
- Familiarity with the API Connector plugin for calling external services
Step-by-step guide
Add 2FA Fields to the User Data Type
Add 2FA Fields to the User Data Type
Go to the Data tab → Data types → User. Add three new fields: 'totp_secret' (text) — stores the secret key for each user, 'two_fa_enabled' (yes/no, default no) — tracks whether the user has enabled 2FA, and 'recovery_codes' (text, list) — stores backup recovery codes. Set Privacy Rules so that totp_secret and recovery_codes are only viewable by the user themselves and never exposed in searches by other users.
Pro tip: Never expose the totp_secret field to the frontend. Use backend workflows to generate and validate TOTP codes so the secret stays server-side.
Expected result: The User data type has three new fields for 2FA: totp_secret, two_fa_enabled, and recovery_codes.
Install a TOTP Plugin or Configure an External TOTP API
Install a TOTP Plugin or Configure an External TOTP API
Search the Bubble plugin marketplace for a TOTP or 2FA plugin. If a suitable plugin is available, install it. Alternatively, use an external TOTP API service via the API Connector. In the API Connector, add a new API called 'TOTP Service'. Add two calls: one to generate a secret (GET/POST that returns a secret key and a QR code URL), and one to verify a code (POST that accepts the secret and the user's six-digit code, returns true/false). Common TOTP services include authenticator APIs or self-hosted solutions.
Expected result: You have a way to generate TOTP secrets and verify codes, either through a plugin or API Connector.
Build the Enable 2FA Page
Build the Enable 2FA Page
Create a page or popup for enabling 2FA. Add a Button labeled 'Enable 2FA'. Create a workflow: when clicked, call the TOTP API to generate a new secret for the user. Save the returned secret to Current User's totp_secret field using a backend workflow (to keep it server-side). Display the QR code image using an Image element with the dynamic source set to the QR code URL returned by the API. Add a Text element showing the manual entry key for users who cannot scan. Below the QR code, add an Input for the user to enter a six-digit verification code and a 'Verify' button.
Expected result: Users see a QR code to scan with Google Authenticator and an input to enter their first verification code.
Verify the Code and Complete 2FA Setup
Verify the Code and Complete 2FA Setup
Create a workflow on the 'Verify' button: call the TOTP verification API with the user's secret and the entered six-digit code. If the API returns success (code is valid), update Current User's two_fa_enabled to 'yes'. Generate 8-10 random recovery codes (use a backend workflow with 'Calculate a random string' repeated 10 times) and save them to Current User's recovery_codes field. Display the recovery codes in a Group so the user can copy them. Show a success message: '2FA has been enabled. Save your recovery codes in a safe place.' If verification fails, show an error: 'Invalid code. Please try again.'
Expected result: After scanning the QR code and entering a valid six-digit code, 2FA is enabled and recovery codes are displayed.
Add 2FA Verification to the Login Flow
Add 2FA Verification to the Login Flow
Modify your login workflow. After the 'Log the user in' action succeeds, add a condition check: 'Only when Current User's two_fa_enabled is yes'. If true, redirect to a '2fa-verify' page instead of the dashboard. On the 2fa-verify page, add an Input for the six-digit code and a 'Verify' button. The verify workflow calls the TOTP API with Current User's totp_secret and the entered code. If valid, redirect to the dashboard. If invalid, show an error message. Add a 'Use recovery code' link that reveals a separate input — verify the entered code against Current User's recovery_codes list, and if found, remove that code from the list (it is single-use).
Pro tip: Add a 'Remember this device' checkbox that sets a cookie or a Device data type entry. On future logins from recognized devices, skip the 2FA step.
Expected result: Users with 2FA enabled are prompted for a six-digit code after logging in, and can use recovery codes as a fallback.
Build a Disable 2FA Option
Build a Disable 2FA Option
In user settings, add a 'Disable 2FA' button that is only visible when Current User's two_fa_enabled is yes. The workflow should first require the user to enter their current six-digit TOTP code to confirm identity. After successful verification, set Current User's two_fa_enabled to 'no', clear the totp_secret field, and clear the recovery_codes list. Show a confirmation message that 2FA has been disabled.
Expected result: Users can disable 2FA from their settings after verifying their current authenticator code.
Complete working example
1DATA TYPE CHANGES:2- User (modified)3 - totp_secret (text) — PRIVATE, backend-only access4 - two_fa_enabled (yes/no, default: no)5 - recovery_codes (list of text) — PRIVATE67PRIVACY RULES:8- User: totp_secret — visible only to Current User (via backend workflow)9- User: recovery_codes — visible only to Current User1011PAGES:12131. PAGE: settings/security (Enable 2FA section)14 - Button "Enable 2FA" (visible when Current User's two_fa_enabled is no)15 - Group QRCode (hidden by default)16 - Image: QR code URL from TOTP API17 - Text: Manual entry key18 - Input VerifyCode (6 digits)19 - Button "Verify & Enable"20 - Group RecoveryCodes (hidden by default)21 - RepeatingGroup showing recovery codes22 - Text: "Save these codes — each can only be used once"23 - Button "Disable 2FA" (visible when Current User's two_fa_enabled is yes)24252. PAGE: 2fa-verify (shown after login)26 - Text: "Enter your 6-digit authentication code"27 - Input TOTPCode28 - Button "Verify"29 - Link "Use recovery code instead"30 - Input RecoveryCode (hidden by default)31 - Button "Verify Recovery Code" (hidden by default)3233WORKFLOWS:341. Enable 2FA clicked → Call TOTP API: generate secret35 → Backend workflow: save secret to Current User's totp_secret36 → Display QR code image → Show QR code group37382. Verify & Enable clicked → Call TOTP API: verify code39 → If valid: Set two_fa_enabled = yes40 → Generate 10 recovery codes (backend workflow)41 → Save recovery codes → Show RecoveryCodes group42 → If invalid: Show error alert43443. Login workflow → Log the user in45 → Only when Current User's two_fa_enabled is yes:46 Go to page 2fa-verify47 → Only when Current User's two_fa_enabled is no:48 Go to page dashboard49504. Verify (2fa page) → Call TOTP API: verify code51 → If valid: Go to page dashboard52 → If invalid: Show error "Invalid code"53545. Verify Recovery Code → Check if entered code is in Current User's recovery_codes55 → If found: Remove code from list → Go to page dashboard56 → If not found: Show error "Invalid recovery code"57586. Disable 2FA → Verify current TOTP code first59 → If valid: Set two_fa_enabled = no, clear totp_secret, clear recovery_codes60 → Show confirmationCommon mistakes when setting up Google two-step verification in Bubble
Why it's a problem: Storing the TOTP secret in a client-visible field
How to avoid: Use Privacy Rules to hide the totp_secret field from client access. All TOTP operations should run through backend workflows.
Why it's a problem: Not generating recovery codes during setup
How to avoid: Always generate 8-10 single-use recovery codes during 2FA setup and display them for the user to save.
Why it's a problem: Allowing TOTP codes to be verified multiple times
How to avoid: Most TOTP APIs handle this automatically. If building custom verification, track the last verified code timestamp and reject codes from the same time window.
Best practices
- Always process TOTP secrets and verification in backend workflows to keep secrets server-side.
- Generate 8-10 recovery codes and make each single-use — remove from the list after use.
- Add rate limiting to the 2FA verification page to prevent brute-force attacks (lock after 5 failed attempts).
- Allow users to regenerate recovery codes from settings after re-verifying their current TOTP code.
- Show a clear warning when users disable 2FA explaining the security implications.
- Test the entire flow end-to-end: enable, login with 2FA, use recovery code, disable, re-enable.
- Consider supporting multiple authenticator apps — any TOTP-compatible app works with the same QR code format.
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm building a Bubble.io app and want to add Google Authenticator 2FA. I need to generate a TOTP secret per user, show a QR code to scan, verify 6-digit codes at login, and provide recovery codes. What TOTP API or plugin should I use, and how do I structure the data types and workflows?
Add two-factor authentication to my app using Google Authenticator. Add totp_secret, two_fa_enabled, and recovery_codes fields to User. Create an enable 2FA flow in settings that shows a QR code and verifies the first code. Modify login to require a 6-digit code when 2FA is enabled.
Frequently asked questions
Does Google Authenticator work with Bubble apps?
Yes. Google Authenticator uses the standard TOTP (Time-based One-Time Password) protocol. Any app that generates TOTP secrets and QR codes in the correct format will work with Google Authenticator, Microsoft Authenticator, Authy, and other TOTP-compatible apps.
Can I use SMS-based 2FA instead of an authenticator app?
Yes, but SMS 2FA is less secure due to SIM-swapping attacks. You can implement SMS 2FA using Twilio or similar services via the API Connector. Authenticator-based TOTP is recommended for better security.
What happens if a user loses their phone?
Recovery codes allow users to log in without their authenticator. They enter a recovery code instead of the 6-digit TOTP code. Each recovery code works once. If they exhaust all recovery codes, an admin must manually disable 2FA on their account.
How do I handle 2FA for admin accounts?
Consider making 2FA mandatory for admin roles. In the admin creation workflow, automatically enable 2FA and require setup before granting admin access.
Is there a Bubble plugin that handles the entire 2FA flow?
Some plugins provide partial TOTP functionality, but most require combining with API calls for full implementation. For complex security requirements, teams like RapidDev can build a complete, tested 2FA system tailored to your app.
Can I enforce 2FA for all users?
Yes. Add a check on page load for authenticated pages: if Current User's two_fa_enabled is 'no', redirect to a setup page that requires enabling 2FA before accessing the app.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation