How to Hash Passwords in ExpressJS using bcrypt

NodeJS logo As a backend developer, you are going to handle a lot of information sent to you by the user and one very common piece of information sent frequently when users sign up to your platform is a password.
But how exactly do we get to store this very important piece of information? Do we store it plainly like a username or email? Nope! We do not.
Rather, we convert this password into a hash using a hashing algorithm.
But what is a hashing algorithm?

A hashing algorithm is basically a one-way algorithm that scrambles data to generate a unique hash that cannot be undone except you provide it with the actual data that was scrambled.

When a hashing algorithm is properly designed, reversing the hash to generate the original data is impossible.

It is similar to an encryption algorithm but the main difference between both of them is that an encryption algorithm is a two-way algorithm while the other is not. Meaning the encryption can be undone if you provide the appropriate key but, a hashing algorithm cannot be undone with a key. Any hacker that gets encrypted passwords simply needs to get the key to unlocking it but any hacker who gets his hands on hashed passwords must guess the actual password.

Now we are done explaining the difference between encryption and hashing let's talk about how we can hash users' passwords in ExpressJS.


A popular node module for hashing passwords in NodeJS is called bcrypt. This is the module we are going to use to hash our passwords.

Step 1

The first thing we need to do after initializing npm is to install the node module bcrypt from npm by running the command below in the terminal.

npm i bcrypt

Step 2

The second thing we need to do is require bcrypt into the file we intend to use it in

const bcrypt = require("bcrypt");

There are 7 methods that you will have access to when using bcrypt. They are :-

  1. .hash()
  2. .genSalt()
  3. .compare()
  4. .compareSync()
  5. .genSaltSync()
  6. .hashSync()
  7. .getRounds()

The 2 most important and the ones you will make use of all the time are what we will talk about today. They are .hash() and .compare()

.hashSync() and .compareSync() do exactly what .hash() and .compare() do but in a synchronous manner.

.hash()

The .hash() method is used in bcrypt to hash a piece of data. It is an asynchronous operation and because of this, it returns a promise. You can decide to use the await keyword for this but it must be done inside an async function.

const bcrypt = require("bcrypt");
const hashUsersPassword = async ( password ) => {
    const salt_rounds = 8
    const hashed_password = await bcrypt.hash(password, salt_rounds)
}

The method has 2 parameters. The first is the data you want to hash and the second is a salt round.

The higher the salt round, the more time the algorithm spends hashing the password but the more secure it will be. We will want to select a number that will give us a perfect balance between security and speed. A salt round that is high enough to give a very secure output but will not slow down the process too much. We are using 8 in this example.

After hashing a password we will get a value similar to $2b$08$1jfS/mzyDoJVZzQwF4MkV.KOqhm6NLZvcuUc38/AppXhFq8dlECOC and this is what we store in our database.

We can also generate a salt using the .genSalt() method bcrypt provides.

const bcrypt = require("bcrypt");
bcrypt.genSalt(salt_rounds, (err, salt) => {
  bcrypt.hash(password, salt, (err, hash) => {
  console.log(hash);
  });
});

The .genSaltSync() method does the exact same thing .genSalt() does but synchronously.

.compare()

The .compare() method is called when a user wants to verify if the data provided matches a hashed value. It is also an asynchronous method and returns a promise but can be called in an async function using the await keyword.

const bcrypt = require("bcrypt");
const verifyPassword = async ( password ) => {
    const hashed_password = await bcrypt.compare(password, hashed_password)
}

When the method is called it returns a boolean. true if the data provided matches the hashed value and false if it does not.

Thank you for reading, let's connect!

Here is my Twitter
And Instagram
And Linkedin