HOW TO: passwordless authentication in API workflow

I’m all about that passwordless UX Passwordless authentication - #7 by blueback09

When I started working with APIs I realized that Bubble also expects a username & password combination for the login action in an API workflow. However, this was pretty easy to work around.

First, you need to create an API key for each user.

This is a group with a button and an html element

The html element has some clever javascript that I stole from someone else on here


`<input type=“text” id=“APIkey” size=“10” value=Current User’s my_API_key>
copy API key

`

Add a workflow to the “new API key” button. Tell it to “Make changes to user”, select “current user”, then stick a random string into the field where you store that user’s current API key (oh, make sure there’s a field to put the user’s API key).

Make sure you put this API-key-generating-group into a place the user can only get to when they’re logged in. Then the user can just get an API key when they need one, and even change it if they want. This API key is basically going to be their “password” when they try to authenticate through the API.

Okay, so now you need at least one API workflow that can be run without authentication. That will be the workflow that authenticates users so that they can then run any other workflow with authentication. The log in process works the same in the API as it does for the rest of Bubble and we’re going to “hack” around it in almost the same way.

The user will POST to the API endpoint, providing their email address (already registered in the app) and their API key (already copied after they logged in and got it). We’re going to run our own little check on those two pieces of information to run a search for users to see if any of them have that email and that API key. If someone matches we’ll record that they used their API key to log in.

Next we’ll assign a temporary password to the user who was turned up in step 1

And finally we’ll log in the user who was turned up in step 1, using the email from the POST and the password from step 2

When this runs successfully it will return a little JSON that will have a “user_id” parameter (the unique id of the user who was just logged in) and a “token” parameter.

What you want to do is put this into the header for your subsequent POSTs to API endpoints that can only be run with authentication. Replace ### with the token you were just given.
Content-Type: application/json Authorization: Bearer ###

5 Likes

What is the use case for this?

I setup a passwordless authentication flow for two of my apps. That means the user doesn’t know what their password is, so they can’t provide it when trying to log in via API.

Could provide a little more info. Do you mean someone just receives a unique link URL to login or they are loading a mobile app and only entering w username?

web app - user receives an email with a link - when they click the link they are signed up or logged in

API - after logging in through the web app, user copies their API key - user sends their email and API key to the authentication API - if the email and key match, then the user gets a token and can call any other API

Very interesting, thank you for the details. Two quick questions:

  1. For the web app, how do manage to create random and unique links for each user?
  2. Do you have a way of making those links expire after the user clicks them?

I use Bubble’s built in “password reset” email. So the token and its expiration are handled by Bubble automatically.

Great stuff. I’d really like to do this with text messaging . Do you have any idea of an integration or service that can generate unique links, which have expiration dates? ( similar to the type bubble sends via email)

Well, I haven’t looked into or attempted to authenticate anyone via text message. I’m not aware of a way to send text messages from Bubble, but I know that Bubble lets you build API calls to other services and I know there are other services that send text messages (twilio).

In theory, since you can generate a temporary password for a user in a workflow, you should be able to accept any authentication you want from anyone first, and then feed “temporary” email and passwords into Bubble to get them signed up or logged in.

So if user ABC requests a sign up code, you could generate it using “calculate random string” and send it to a service that sends them an SMS. At the same time you could file the temporary string in the database. If you need to be sure of the phone number, then you might have to get confirmation back from a service that can receive text messages. Otherwise you can just assume that if someone enters that secret code within a minute or two it must be the person who requested it.

All you need, aside from SMS send/receive, is to generate your own secret code and save it in a thing. Just save it along with the date/time you created it and only accept it for a certain period of time. You don’t need any other service for that.

So, how would you handle changing the users email where a password is required as part of the change users credentials workflow as an additional security check?

Haven’t tried that yet.

I suppose you could store the email they requested and send a password reset email to the new email address. If it comes back confirmed then you could change their primary email to the new email.

Just glancing through the workflow actions it looks like the old password is required. Maybe you can just put an “assign temporary password” action first and then refer to the results of that action when the “update user’s credentials” action needs the “old” password.

Did you ever find a solution that worked reliably for the change in email address situation? I’d be keen to implement a password less solution but 5% of our users change their email addresses over time.

I stopped trying to use a passwordless flow.

1 Like

Curious - why did you stop with the password-less flow? I am working on a project where a random string token/key could have value as a way to allow users to self-provision access to their data through the API. I know these can be assigned in settings for overall purposes, but then they would need to be manually handed out to users.

Does it create further complexity in other ways?

It was a while ago. Mostly I just stopped trying to do things that Bubble doesn’t support. Even if you can technically hack together a solution, it’s contrary to Bubble’s design philosophy, so it’s brittle, and Bubble won’t necessarily understand what you’re doing or provide any support.

The whole appeal of Bubble is that it’s a long list of options you can slap together and have them all “just work” right away at scale. Like Legos. If there’s a part Legos doesn’t provide, you can try to bung together what you want with hot glue but if it doesn’t work Lego isn’t going to help you.

The OAuth logins (facebook, google, etc) are similar to passwordless in practice; maybe try those.

This is insightful, and something to keep in mind from a design perspective. Just because something can be done doesn’t mean it’s a good choice longer term for maintainability.

The OAuth approach keeps getting mentioned, I’m looking for any clear documentation or tutorials for how that could be implemented to create API access tokens that users could manage themselves.

But I have more to learn - I always think of OAuth in terms of third-party user authentication to allow basic application access, and obviously it can be used for more.

You can just use the random string function to create API access tokens.