I won’t go into the “why” of passwordless authentication. 1
Bubble has a built-in authentication system that only works with passwords. It does heavily leverage 3rd-party authentication (OAuth, Google, Facebook, etc) which has a similar UX to passwordless authentication, which can work instead of, or in addition to, this approach.
Here’s how to “hack” Bubble’s native password-based login system to provide a passwordless experience for your users.
The signup process is mostly unchanged, with the minor exception that you’re not going to collect a password from the user. You’re just going to toss a random number in there. You’re going to skip the normal log in process entirely. Any time a user wants to log in you’re going to send them one of Bubble’s built-in password reset emails, which return them to Bubble’s built-in password reset page. Bubble will create a new random temporary password and log them in. They’ll remain logged in for a while, but no longer than one month.
The following instructions assume a basic familiarity with Bubble’s interface.
- start with a new, blank app
- insert the default header into the index page
- add a new page by cloning the index page; name it “profile”
- open the header for editing
- expand the elements tree; expand group B
- copy and paste the login/signup group so that group B now has two identical groups under it
- change the names of the two button groups to something meaningful
- I suggest “login/signup” and “logout/profile”
- change the names of the buttons themselves to reflect this
- I suggest that the button next to “log out” be set (using dynamic data) to the “current user’s email:extract alias”
- Set visibility conditions
- under both button groups, uncheck the “this element is visible on page load” box so that the buttons default to invisible
- under both button groups, on the conditional tab, create a new condition
- set the condition to “current user is logged in” OR “current user is logged out”
- set the property to change to “this element is visible” and check the box so that the appropriate group will set itself back to visible. That way the user will see the correct buttons for their logged in/out status
- open the header’s workflows for editing
- go ahead and create a workflow that navigates to the index page when the header’s logo is clicked (just one of those design best practices that Bubble’s default app ignores)
- add a workflow that logs the user out when button “log out” is clicked (also might as well navigate back to the index page)
- add a workflow that navigates to the user’s profile page when the button displaying their email is clicked
- you should see 5 workflows: button current user’s email is clicked, button log in is clicked, button log out is clicked, button sign up is clicked, logo is clicked
- make sure that the header has “signup / login popup A” in its element tree. If it doesn’t, then insert that popup from the reusable elements
- open reusable element signup / login popup for editing
- in the element tree, make group “signup” visible if it isn’t already
- all you need here is an email input and a “confirm email” button
- delete the email and email confirmation fields
- change the name of button “sign up” to “sign me up”
- under the element tree, make group “signup” invisible and make group “login” visible
- again, all you need here is an email input and a button
- delete the “password” input, the “remember me” checkbox, and the “forgot password” button
- change the name of button “log in” to “send me a login link”
- under the element tree, select group “reset password”
- select “delete” in popup reset password’s parameters
- in the element tree, make group “signup” visible if it isn’t already
- open the workflows for reusable element signup / login popup for editing
- workflow: button sign me up is clicked
- first action: sign the user up
- email should be input email’s value
- change password to “calculate formulat” and “generate random string” and just set it to like 100 characters with all boxes checked
- uncheck require password confirmation
- uncheck send an email to confirm the email
- change remember the email to yes
- next action: send password reset email
- email to reset should be input email’s value
- change the subject and body to something that makes sense
- leave an empty line under the body text so that the reset link isn’t jammed up against the body text
- next action: hide signup / login popup
- next action: go to page index
- first action: sign the user up
- workflow: button send me a login link is clicked
- delete the log the user in action
- first action: send password reset email
- change email to reset to “input email (log in)’s value”
- change the subject and body to something sensible and be sure to leave a couple empty lines after the text so that the link is on its own line in the email
- next action: hide signup / login popup
- next action: go to page index
- leave the workflows for “switch to login” and “switch to signup” alone
- now you should see four workflows: button confirm my email is clicked, button send me a login link is clicked, button switch to login is clicked, button switch to sign up is clicked
- workflow: button sign me up is clicked
- open the app’s Data for editing
- under tab data types, click on “user” (it should be the only data type anyway)
- create a new field and name it “trust_time” so that we can set an upper limit on the length of time a user can remain logged in
- open page reset_pw for editing
- change text “reset your password” to “confirming email”
- delete the “password” and “re-type password” inputs
- change text “this page lets you reset your password” to “If you are not redirected automatically, please click this button.”
- change the name of button “CONFIRM” to “click me”
- open page reset_pw’s workflows for editing
- under workflow “page is loaded” add constraint and when “is reset password token valid = yes”
- add first action: assign a temp password to a user with user = Current User
- next action: reset password with both password and confirmation set to “result of step 1”
- next action: make changes to current user. click change another field. enter trust_time = current date/time
- next action: go to page index
- build the same actions under button click me as a backup in case the automatic workflow doesn’t run
- under workflow “page is loaded” add constraint and when “is reset password token valid = yes”
- open page index’s workflows for editing
- add a new event, user is logged in
- and when [current user] [‘s trust_time] [+(months):] [type 1 and then click to the right of the box so 1 turns yellow] [<] [current date/time]
- so this takes the date/time stored in trust_time (back when the user’s credentials were reset), adds one month to it, and tests to see if that date is less than (older than) the current date/time. Or, in human-speak, it tests to see if the trust_time is more than one month ago
- create action log the user out
- add a new event, user is logged in
- make up a test email and use Mailinator to try signing up.
- I assume you already get it if you’re trying to implement it in your Bubble app. ↩
Great lesson.
It would be nice to have a video lesson on this.
Thanks