# How to securely authenticate users with an external database connection?

**URL:** <https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856>\
**Category:** Get Help\
**Tags:** custom-database-connections, connections\
**Created:** [May 23, 2024, 5:03pm UTC](https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856 "2024-05-23T17:03:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![steve-ir](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/steve-ir/32/57378_2.png) [@steve-ir](https://community.auth0.com/u/steve-ir)\
**Post date:** [May 23, 2024, 5:03pm UTC](https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856/1 "2024-05-23T17:03:58Z")

</div>

I don’t understand how to securely implement the external database login flow. Based on the examples provided in the documentation: [Custom Database Action Script Execution Best Practices](https://auth0.com/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts/execution#promise-object)

You are supposed to hash the password before sending it to your external database API. But in our database we also store a separately hashed password. How are we supposed to authenticate a hashed password against another hashed password? The only way I can think of is to first retrieve the user’s password hash from the external database, then hash the plaintext password with the same salt, then send that hash back to the external database. This requires two API calls and also exposes an endpoint to retrieve password hashes for any user.

Am I missing something?

---

<div class="post-metadata">

**Author:** ![rueben.tiow](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/rueben.tiow/32/11646_2.png) [@rueben.tiow](https://community.auth0.com/u/rueben.tiow)\
**Post date:** [May 24, 2024, 7:49pm UTC](https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856/3 "2024-05-24T19:49:45Z")

</div>

Hi @steve-ir,

There should be built-in Database Action scripts that you can use to implement this for you.

(Reference: [Custom Database Action Script Templates](https://auth0.com/docs/authenticate/database-connections/custom-db/templates))

However, if you decide to implement the login script yourself, you must hash the password before sending it to your external database API. You are supposed to take the password supplied by the user during login and encrypt it before sending it to your external database.

E.x

```auto
function login(userNameOrEmail, password, callback) {
  // Send credentials to external database API
  let hashedPassword = hash(password);

  let options = {
    url: "https://example.com/api/authenticate",
    body: {
      email: userNameOrEmail,
      password: hashedPassword
    }
  };

  send(options, (err, profileData) => {
    // Return error in callback if authentication is unsuccessful
    if (err) {
      return callback(new WrongUsernameOrPasswordError(userNameOrEmail, "My custom error message."));
    } else {
      // Return profile data in callback if authentication is successful
      let profile = {
        username: profileData.username,
        email: profileData.emailAddress,
        user_id: profileData.userId
      };

      return callback(null, profile);
    }
  });
}

```

See the [Login Script Templates](https://auth0.com/docs/authenticate/database-connections/custom-db/templates/login) documentation.

Thanks,  
Rueben

---

<div class="post-metadata">

**Author:** ![steve-ir](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/steve-ir/32/57378_2.png) [@steve-ir](https://community.auth0.com/u/steve-ir)\
**Post date:** [May 24, 2024, 10:35pm UTC](https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856/4 "2024-05-24T22:35:37Z")

</div>

Hi @rueben.tiow thanks for the response.

I’m unclear on what you said here:

> you must hash the password before sending it to your external database API. You are supposed to take the password supplied by the user during login and encrypt it before sending it to your external database.

Are we supposed to hash the plaintext password or encrypt it?  
From Auth0’s own blog, there is a distinct difference between the two: [Encoding, Encryption, and Hashing](https://auth0.com/blog/encoding-encryption-hashing/)

If it really is supposed to be hashed, then the example script makes no sense because the user’s password is also stored as a hash in the external DB. We can’t compare two hashes without using the same salt, but the salt is unique for every password so the connection script cannot know that ahead of time. Thus we would need to make two api calls, one to retrieve the salt and the second to authenticate the user, which is very inefficient.

If the password should be encrypted, that would make a little bit more sense, but that isn’t how the example script is written. It would introduce a shared secret that both Auth0 and the external API would need to know and isn’t detailed in the documentation.

The last option I can think of is to retrieve the entire user profile from the external API, then verify the password on the connection script side.

Which is the recommended solution? Or is there something else I didn’t think of?

---

<div class="post-metadata">

**Author:** ![rueben.tiow](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/rueben.tiow/32/11646_2.png) [@rueben.tiow](https://community.auth0.com/u/rueben.tiow)\
**Post date:** [May 28, 2024, 11:12pm UTC](https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856/5 "2024-05-28T23:12:52Z")

</div>

Hi @steve-ir,

Thanks for the reply.

You are supposed to **encrypt** the password, which is the recommended solution. You can find more details [here](https://auth0.com/docs/authenticate/database-connections/custom-db/templates/login#encryption).

Additionally, the script I shared is a pseudo-javascript example of how you could implement the login function. For language-specific examples, read [Language-specific script examples](https://auth0.com/docs/authenticate/database-connections/custom-db/templates/login#language-specific-script-examples).

Generally, you should be able to use one of those scripts to securely authenticate your users without having to build the script yourself. Have you had a chance to try it yet?

Thanks,  
Rueben

---

<div class="post-metadata">

**Author:** ![steve-ir](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/steve-ir/32/57378_2.png) [@steve-ir](https://community.auth0.com/u/steve-ir)\
**Post date:** [May 29, 2024, 6:19pm UTC](https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856/6 "2024-05-29T18:19:05Z")

</div>

@rueben.tiow Ok thanks for the clarification.

The example you’ve pointed to [here](https://auth0.com/docs/authenticate/database-connections/custom-db/templates/login#encryption) uses bcrypt to **hash** the password, which is not encryption and is not a reversible operation. The documentation needs to be updated to reflect this.

The [second link](https://auth0.com/docs/authenticate/database-connections/custom-db/templates/login#language-specific-script-examples) correctly demonstrates how to use bcrypt to verify the password against `dbPasswordHash` but it doesn’t detail how to retrieve `dbPasswordHash` in the first place. Also, it’s not useable out of the box:

```auto
const msg = 'Please implement the Login script for this database connection ' +
    'at https://manage.auth0.com/#/connections/database';

```

That said, implementing these functions is pretty trivial besides the question about how to securely compare the plaintext password with the hashed value stored in our external database. I’m able to connect Auth0 to my external database API, and all of the scripts are working.

I am going to follow your recommendation to **encrypt** the plaintext password and then decrypt it on our end. I just would like to point out that the current state of documentation around this does not reflect that solution.

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/auth0/original/3X/b/5/b560f266932fcce5d57f09a6595bd50518cae3f3.jpeg) [@system](https://community.auth0.com/u/system)\
**Post date:** [June 12, 2024, 6:20pm UTC](https://community.auth0.com/t/how-to-securely-authenticate-users-with-an-external-database-connection/134856/7 "2024-06-12T18:20:01Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
