How to make secure 2 step verification (2FA)

Hi! I am struggling with making safe 2 step verification in Bubble.

I scoured the web looking for tutorials and this is what i found in most cases:

  1. Users Logs in, in Frontend Workflow we Make a change in User adding generated code (via Calculate formula) and expiration date. Send an email to the user with generated code.
  2. User is prompted to provide passcode form the email. Bubble checks if passcode = code saved in User’s Database (again, on the fronted)

This works but it is not very secure.

  • We should not Log the user in before we conclude verification process
  • Good practice is that newly generated code invalidates previous one
  • And most important - if we perform “check” on the frontend workflow the correct code is provided to the browser and can be found via Developer Tools, wich is like :exploding_head:

So, here is my solution. It moves process to the backend workflow (so you need paid plan for that to work)

  1. Create new Data Type, let say “2step” with fields: email, expiration date, success and verification code
    Zrzut ekranu 2023-01-8 o 07.32.48

  2. On the UI side, clicking on the Sign Up Button moves User to “Verification Page” and Schedules a backend workflow, sending User emails as parameter

  3. On the Backend side we run workflow to create new “2step” and send an email to the User.

  4. Now we need to make an API call. Get API Connector from Bubble Plugin store. Remember to generate your API Key in Settings → API → API Tokens

  1. On the fronted side, User sees “provide verification code” prompt, something like this

  2. Our final frontend workflow looks like this. We call our backend workflow with provided passcode and User’s email.

  3. On the backend we preform check if this email-passcode is found in database. If jest, we mark it as a successful verification

  • note, that i skipped date expiration here, but it can be easily added. or you can just run scheduled workflow to delete this entry after 5 minutes to make thins clean.

  1. In “Return data from API” return results of step 1 - success.

  2. On the frontend we can now Log the User in if we get “yes” response! Also we can build logic around it regarding interface; we can show error message if we get “no” and so on.

So that’s it. I am no security expert and I would love to hear from more experienced folks if this way is as secure as i think it is :slight_smile:


I like this. Thanks for sharing.

Also made it easier for me to understand the use of the return data from API.