> For the complete documentation index, see [llms.txt](https://manual.bubble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual.bubble.io/help-guides/data/user-accounts.md).

# User accounts

This article covers how you create and manage users in your app

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FjaZFND9sQ0zm6noa1B9r%2Fprofile-pic.png?alt=media&amp;token=f4e6ffbc-da87-46fb-831d-cbcc3b1323ba" alt=""><figcaption></figcaption></figure>

In this article, we'll look at how Bubble handles setting up and managing user accounts.

Technically, users are just another data type in your app's database. But user accounts carry a lot of responsibility, so Bubble treats the *User* data type a bit differently from the rest:

<table><thead><tr><th width="235.828125">Feature</th><th>What Bubble does</th></tr></thead><tbody><tr><td>Secure credentials</td><td>Passwords are hashed and salted, and user data is encrypted both in transit and at rest.</td></tr><tr><td>Signing up and logging in</td><td>Creating accounts, logging users in, and remembering them between sessions is handled for you.</td></tr><tr><td>Account security features</td><td>Email confirmation, password resets, two-factor authentication (2FA), magic login links, and temporary passwords are built in.</td></tr><tr><td>Temporary users</td><td>Visitors who haven't signed up get a temporary user. Data saved on that user carries over when they sign up, which is useful for things like a shopping cart.</td></tr><tr><td>Privacy rules</td><td>Privacy rules can compare a record with the current user, so you can control access to data based on who the user is and what's stored on them.</td></tr></tbody></table>

Account security is hard to get right, and it works much the same way across most apps. That's why Bubble takes care of the underlying mechanics: it saves you development time and keeps the security side of user accounts up to date without extra work on your part.

### What is a user account?

Most of us have dozens or even hundreds of user accounts: we're logged in to our phones, our email, social media, forums, and even newspapers. We all know what they are, so let's change perspective a bit: *why* does an app need user accounts?

The first answer is that not every app does. You can build a highly useful app where nobody ever creates an account, even one that lets visitors add and change things in the database. So it's worth separating two ideas: your app can have *users*, *registered users*, or both. Every visitor is a user, but only those who sign up become registered users. This article focuses on registered users, meaning users who have signed up with an email and password or through a [third-party service](#user-content-fn-1)[^1].

Registering users serves many purposes:

<table><thead><tr><th width="212.3359375">Purpose</th><th>Description</th></tr></thead><tbody><tr><td>Keeping data private</td><td>In many apps, a user should only see their own data, or the data of a select group of other users.</td></tr><tr><td>Saving settings</td><td>Users can save preferences and profile details that are still there the next time they use the app.</td></tr><tr><td>Controlling access</td><td>Some apps only let registered users access their pages.</td></tr><tr><td>Assigning roles and permissions</td><td>Once you can identify each user, you can assign roles that control what they're allowed to see and do.</td></tr><tr><td>Personalization</td><td>Apps like social networks and e-commerce stores can show each user a personalized stream of content.</td></tr><tr><td>Teaming up</td><td>Apps where people share data and collaborate need to know who each person is to control who has access to what.</td></tr><tr><td>Payment processing</td><td>Orders and payment history are usually attached to a permanent user.</td></tr><tr><td>Communication</td><td>Knowing who your users are lets you reach them in the app or through channels like email.</td></tr></tbody></table>

As you can see, user accounts aren't only about security and privacy. Just like any other data type, you can add as many fields to the User data type as you need. The User type also comes with a few fields of its own to handle the account. These can't be changed or deleted, and they're the same in every Bubble app.

### Built-in fields

Like other data types, the User type has a set of [built-in fields](#user-content-fn-2)[^2]. On top of those, it comes with three fields of its own:

<table><thead><tr><th width="173.95703125">Field</th><th>Visible in the database editor</th><th>Description</th></tr></thead><tbody><tr><td>Email</td><td>Yes</td><td>The user's email address, used to sign up and log in.</td></tr><tr><td>Password</td><td>No</td><td>The user's password, stored as a secure hash.</td></tr><tr><td>Email confirmed</td><td>No</td><td>A yes/no value that shows whether the user has confirmed their email.</td></tr></tbody></table>

#### Email

The email field can't be empty on a registered user, and it needs to be a valid email address. Every user in your app needs a unique email address, so two users can't sign up with the same one.

#### Password

The password field is different from every other field: it's invisible, even to you as the app developer. Bubble stores passwords following industry-standard practices.

<details>

<summary>How passwords are kept safe</summary>

Bubble protects user passwords with two techniques: one-way hashing and salting.

**One-way hashing** turns the password into a fixed-length code, called a hash. Once a password has been hashed, it can't be turned back into its original form, and the hash is what's stored in the database. When a user logs in, Bubble hashes the password they entered and compares it to the stored hash. If the two match, the user is logged in.

**Salting** adds a random string of characters to the password before it's hashed. For example, if two users both choose the password "password123", each password gets its own random string, such as "password123" + "pEoW82!", so the two hashes come out completely different. That means an attacker can't use a list of precomputed hashes for common passwords to work out what the original password was.

Bubble only compares hashes and never knows what the original password is. Even if someone gained access to the database, they couldn't see the actual passwords, and not even Bubble can.

One-way hashing combined with salting is widely regarded as standard practice for storing passwords.

</details>

#### Email confirmed

The *Email confirmed* field is also invisible. It holds a yes/no value that shows whether the user has confirmed their email address. The value changes to *yes* when the user clicks the link in a confirmation email, sent either by the **Send confirmation email** action or by the **Sign the user up** action with *Send an email to confirm the email* checked.

You can't change this field directly. Only the user can update it, by confirming their email.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fa2HJ7nkyIVVOaZvniXTv%2Femail-confirmed.png?alt=media&amp;token=c2cd19f8-49f5-495d-93ba-33cdae5f7d53" alt="Finding the Current User&#x27;s email confirmed data source in the dynamic expression editor."><figcaption><p>The email confirmed field is invisible in the database editor, but you can use its value in an expression, such as <code>Current User's email confirmed</code>.</p></figcaption></figure>

### Signing up users

This article covers the most common actions[^3] for user accounts, but not every one. To see all the actions and operators[^4] available for users, check out the references below:

Reference: Account actions\
Reference: User operators

Bubble handles the technical side of signing users up, but the design and user experience are entirely up to you.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FyojQBL32U84cYC52PydJ%2Fsignup.jpg?alt=media&#x26;token=65e913c8-4bea-4997-9078-8fa79f6e52f0" alt=""><figcaption><p>Bubble handles security and communication with the database, but the user experience is up to you.</p></figcaption></figure>

To sign a user up, you need two pieces of text from them: a valid email address that isn't already in use in your app, and a password. You collect these with input elements and pass them to the **Sign the user up** action.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FvXaacnawIRFhmTgGB1E2%2Flog-user-in.png?alt=media&amp;token=eb3c4c96-90d1-4923-8be6-49bac45ccd76" alt="Bubble&#x27;s workflow editor showing the Log the user in action."><figcaption></figcaption></figure>

The **Sign the user up** action has these main properties:

| Property                           | Description                                                                        |
| ---------------------------------- | ---------------------------------------------------------------------------------- |
| Email                              | The email address the user signs up with.                                          |
| Password                           | The password the user chooses.                                                     |
| Require a password confirmation    | When checked, the user types their password twice, and the two have to match.      |
| Send an email to confirm the email | When checked, Bubble sends the user a confirmation email right after they sign up. |
| Change another field               | Lets you save other fields on the new user at the same time, such as their name.   |

#### Setting up a signup form

{% stepper %}
{% step %}

#### Add the input elements

Add an input for the email address and one for the password. If you want users to confirm their password, add a second password input.

Set the email input's content format to *Email* and the password inputs' content format to *Password*, so the email is validated and the password characters are hidden.
{% endstep %}

{% step %}

#### Start a workflow

Add a button, such as *Sign up*, and start a workflow with the **An element is clicked** event.
{% endstep %}

{% step %}

#### Add the Sign the user up action

Add the **Sign the user up** action. Set *Email* to the email input's value and *Password* to the password input's value. If you added a second password input, check *Require a password confirmation* and set *Password confirmation* to that input's value.
{% endstep %}

{% step %}

#### Save more information (optional)

If you collect more information at signup, like the user's name, check *Change another field* and map each field to its input.
{% endstep %}

{% step %}

#### Send the user onward

Add a **Go to page** action to take the new user where you want them, such as a dashboard or a welcome page.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Input elements can format what the user types, such as hiding password characters, and can check that the input matches an expected format, such as a valid email address. We recommend using both in your signup and login forms.

Article section: Input elements
{% endhint %}

The email and password are sent to Bubble's server encrypted, and the password is hashed and salted, so no one can read it, not even the Bubble team.

As soon as the action runs, Bubble creates the account and the user is logged in. The session lasts for 365 days, or until the user logs out or clears the cookies in their browser.

### Logging users in

Logging a user in works much like signing them up. The **Log the user in** action needs two inputs: the email and the password. Bubble sends them to the server encrypted to check the credentials, and if both are correct, the user is logged in.

The *Stay logged in* property controls how long the session lasts:

| Stay logged in | Session length |
| -------------- | -------------- |
| Checked        | 365 days       |
| Unchecked      | 24 hours       |

A common setup is to add a *Remember me* checkbox to your login form and use its value for the *Stay logged in* property, so each user can choose.

### Signing up and logging in with a third-party service

Instead of an email and password, you can let users sign up and log in with an account they already have, such as Google, Facebook, LinkedIn, or X (Twitter). This is often called social login, and it works through a standard called OAuth.

<details>

<summary>What is OAuth?</summary>

OAuth is an open standard that lets one app get limited access to a user's account on another service, without ever seeing that user's password.

When a user clicks a button like *Log in with Google*, they're sent to Google's own login page. After they log in and approve the request, Google sends your app a token that confirms who the user is and grants the access they agreed to. Your app never handles their Google password.

</details>

Third-party login has a couple of advantages:

* Users can sign up in a few clicks and don't need to remember another password.
* Depending on the service and the permissions the user grants, your app can also fetch data on their behalf, such as their email address or profile picture.

Bubble offers plugins for several services, and you can find more in the plugin marketplace. You can also connect to other providers with the API Connector.

{% hint style="info" %}
If you need users to log in through their organization's identity provider (IdP), you can set up SSO with the WorkOS plugin or the API Connector.
{% endhint %}

#### Example: logging in with Facebook

{% hint style="info" %}
This example describes how Facebook login works overall. To read more about the Facebook plugin's properties, check out the resources below:

Article: Using the Facebook Graph API plugin\
Reference: Facebook
{% endhint %}

Let's say your app has a button labeled *Log in with Facebook*.

When you set up this flow, you define the level of authorization[^5] your app needs. By default, most services only share the user's public profile and email address, but you can ask for more permissions if your app needs them.

Only ask for the permissions your app actually uses. It's better for your users' privacy and security, and a long list of permission requests can lead to fewer users signing up.

When a user signs up with Facebook, Bubble creates a new user in the database, just like a regular signup with an email and password. The difference is how they log in later. Since they never set a password, they log in with Facebook again. If they're already logged in to Facebook in the same browser, that's usually a single click.

#### Mixing traditional and social logins

A user can have both a traditional login and one or more social logins. This can play out in a few different ways, which we cover in the article series below:

Article series: OAuth plugins

### Temporary users

Signing a user up gives them an email address and a permanent place in your database. In many cases, it's also when they choose a password.

But Bubble starts keeping track of who the user is before that. When someone visits your app for the first time, Bubble saves a cookie in their browser and creates a temporary user. That lets you remember who the user is during their visit and build logic that relies on data stored on the current user, such as:

* Saving preferences and settings
* Storing a shopping cart
* Personalizing the experience

A temporary user stays active on the same device for 72 hours. When the user signs up, Bubble automatically transfers the data stored on the temporary user to their new account.

{% hint style="info" %}
Because every visitor gets a temporary user, the `Current User` data source is never empty, as long as cookies are allowed. To check whether a user has actually signed up and logged in, use the [*is logged in*](#user-content-fn-6)[^6] operator, such as `Current User is logged in`.
{% endhint %}

{% hint style="warning" %}
Data stored on a temporary user is transferred automatically when the user signs up, but not when they log in to an existing account.
{% endhint %}

There's one exception: in the **Settings** tab, you can stop Bubble from setting cookies on new visitors automatically. If you do, Bubble doesn't create a temporary user until the visitor accepts cookies through the **Opt-in to cookies** action. Until then, anything stored on the current user is lost when they close the browser tab.

### User accounts in native mobile apps

Bubble for native mobile apps uses the same user accounts as your web app within the same project. A user who signs up on the web can log in to your iOS or Android app with the same credentials, and the other way around.

| Action                                       | How it works                                                                                                                                                                                                                                                     |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Sign the user up** and **Log the user in** | Work the same way as in your web app.                                                                                                                                                                                                                            |
| **Signup/login with a web browser**          | Only available in native mobile apps. Opens a page from your web app to sign up or log in the user, so you can reuse your existing signup and login page instead of building a separate one for mobile. Supports email and password login, OAuth login, and 2FA. |

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FS8hUC4W5LEoQKm65x1z7%2Flogin-web-browser.png?alt=media&amp;token=84161620-b8f0-4157-a61d-5801ac545b91" alt="Bubble&#x27;s workflow editor showing the Signup/login with a web browser action"><figcaption><p>The <em>Signup/login with a web browser</em> action lets your native mobile app reuse a signup or login page from your web app.</p></figcaption></figure>

### Other account actions

Beyond signing up and logging in, Bubble includes actions for most of the account tasks your app is likely to need:

| Action                                             | What it does                                                                                     |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| **Send confirmation email**                        | Sends the user an email with a link to confirm their email address.                              |
| **Send password reset email**                      | Sends the user an email with a link to reset their password. Reset links are valid for 24 hours. |
| **Reset password**                                 | Sets a new password for a user who followed a password reset link.                               |
| **Send magic login link**                          | Sends the user a link that logs them in without a password.                                      |
| **Update the user's credentials**                  | Changes the current user's email or password. Requires their current password.                   |
| **Assign a temp password to a user**               | Generates a temporary password for a user. Temporary passwords don't expire automatically.       |
| **Create an account for someone else**             | Creates a new user account without logging anyone in, such as when an admin invites a user.      |
| **Log the user out**                               | Logs the current user out.                                                                       |
| **Log out other user's sessions**                  | Logs the current user out on all other devices.                                                  |
| **Opt-in to cookies** and **Opt-out from cookies** | Lets users accept or decline the cookies Bubble sets.                                            |
| 2FA actions                                        | A set of actions for setting up, checking, and disabling two-factor authentication.              |

Reference: Account actions

### FAQ: User accounts

<details>

<summary>How can I help my users log in if I can't see their password?</summary>

It's widely regarded as a basic security practice that no one, not even an app's developer, should have access to a user's password. If a user has lost their password, you can help them reset it or assign them a temporary one.

</details>

<details>

<summary>Can I log users out of sessions on multiple devices?</summary>

Yes, with the **Log out other user's sessions** action. It logs the user out on every device *except* the one running the action. To log out the current session too, follow it with the **Log the user out** action.

</details>

<details>

<summary>How long does a user stay logged in?</summary>

It depends on the type of user and how they logged in:

| Situation                                 | Session length              |
| ----------------------------------------- | --------------------------- |
| Temporary user (hasn't signed up)         | 72 hours on the same device |
| Logged in with *Stay logged in* unchecked | 24 hours                    |
| Logged in with *Stay logged in* checked   | 365 days                    |

A user can also be logged out earlier if:

* The **Log the user out** action runs
* The **Log out other user's sessions** action runs on another device
* The user clears their browser's cookies

</details>

<details>

<summary>Is there a difference between Make changes to a thing with Current User as the thing, and Make changes to current user?</summary>

No. Both let you change any custom field on the user.

</details>

<details>

<summary>Why can't I change the user's email or password with the Make changes to current user action?</summary>

The email and password are the user's *credentials*, so Bubble handles them with a dedicated action: **Update the user's credentials**. For security reasons, this action requires the user's current password in its *Old password* property, so you'll need an input element where the user can type it.

</details>

<details>

<summary>How do I check whether a user is logged in?</summary>

Use the *is logged in* operator on the `Current User` data source, such as `Current User is logged in`. Checking whether `Current User` is empty doesn't work, since every visitor has a temporary user.

</details>

<details>

<summary>Can I create an account on behalf of someone else?</summary>

Yes, with the **Create an account for someone else** action. It creates the account without logging anyone in, which is useful when an admin adds users or invites them by email.

</details>

<details>

<summary>Does data on a temporary user carry over when they log in?</summary>

No. Data on a temporary user only transfers automatically when the user signs up. If an existing user logs in, data saved on their temporary user isn't moved to their account.

</details>

## Other ways to learn

<details>

<summary>Video lessons</summary>

* [User Authentication: Bubble Introduction Series \[6/10\]](https://www.youtube.com/watch?v=gn0TixSCmGU)
* [Adding User Settings | Build Your First Bubble App \[13/20\]](https://www.youtube.com/watch?v=wwHOKUygxHI)
* [How to Create An Account For Someone Else](https://www.youtube.com/watch?v=gwocxW4OlG4)
* [Building a sign-up system](https://youtu.be/l6NQdipDtmI)

</details>

[^1]: **Single sign-on** is when you sign up and log into an app using a third-party account such Google, LinkedIn or Facebook instead of providing a username and password.\
    \
    Bubble has several plugins that let you set this up:\
    \
    **Reference**: [Facebook SSO plugin](/core-resources/bubble-made-plugins/facebook.md)\
    **Reference**: [Twitter SSO plugin](/core-resources/bubble-made-plugins/twitter.md)i

    **Reference**: [LinkedIn SSO plugin](/core-resources/bubble-made-plugins/linkedin.md)

    Other plugins are also available, or you can set up your own methods using the [API Connector](/help-guides/integrations/api/the-api-connector.md).

[^2]: The User type has these built-in fields, like other data types:

    * Unique ID
    * Created Date
    * Modified Date
    * Slug

    Other data types also have a *Creator* field, which the User type doesn't have.

    Article section: Data type built-in fields

[^3]: Actions are the part of a workflow that performs a specific task. For user accounts, that could be signing the user up, logging them in, or making changes to their profile.

    Article series: Workflows

[^4]: *Operators* are the part of an expression that follows the data source.\
    \
    For users, `Current User` would be the data source and *is logged in* would be the operator:\
    \
    `Current User is logged in`

[^5]: *Authorization* is the process of determining what an identified user has access to.

    In this context, it determines what data your app is allowed to access from the third-party service.

[^6]: The *is logged in* operator can be applied to the `Current User` data source to check whether the user is logged in.\
    \
    Reference: [...is logged in operator](https://manual.bubble.io/~/changes/1300/help-guides/data/pages/-MTpydODwo34mk5NucJy#...is-logged-in)\
    Reference: [...isn't logged in operator](https://manual.bubble.io/~/changes/1300/help-guides/data/pages/-MTpydODwo34mk5NucJy#...isnt-logged-in)
