How to Use Bcrypt for Password Hashing in Node.js
Tags: node, mongodb, mongoose, backenddevelopment
Published: 2024-07-01 04:43:28

##Page Content
* [Introduction to Bcrypt](#introduction-to-bcrypt)
* [Getting Started with Bcrypt](#getting-started-with-bcrypt)
* [Using Bcrypt with Mongoose Pre Save Middleware](#using-bcrypt-with-mongoose-pre-save-middleware)
* [Implementing Password Comparison with Instance Methods in a Nodejs and Mongoose Application](#implementing-password-comparison-with-instance-methods-in-a-nodejs-and-mongoose-application)
* [Password Verification in Nodejs Using Bcrypt with Mongoose Instance Methods](#password-verification-in-nodejs-using-bcrypt-with-mongoose-instance-methods)
* [Conclusion](#conclusion)

##Introduction to Bcrypt

Securing user data has become paramount, and one of the most critical aspects of this security is password protection. This is where password hashing comes into play.

**Password hashing:** is a process of transforming a plain text password into a fixed length string of characters, which is typically a cryptographic hash.

**Bcrypt:** A library to help you hash passwords.

##Getting started with Bcrypt


![Let's get started](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kch2h1a058usjm9dcqcd.gif)

To start using bcrypt in your Node.js application, you first need to install it. Below are the instructions for installing bcrypt:

`npm install bcrypt`

##Using Bcrypt with Mongoose Pre-Save Middleware

In this section, we will explore how to use bcrypt with Mongoose pre save middleware to securely hash passwords before saving them to the database. This approach ensures that plain text passwords are never stored in the database, enhancing the security of your Node.js application.

Before we begin, make sure you have installed both mongoose and bcrypt in your project:

`npm install mongoose bcrypt`

###Importing required modules

```
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
```

The pre save middleware is a function that runs before a document is saved to the database. This  method it is an important way to hash the user's password:

```
// pre save middleware
UserSchema.pre("save", async function () {
  //    hashing the password
  const salt = await bcrypt.genSalt(15);
  this.password = await hash(this.password, salt);
});
```

##Implementing Password Comparison with Instance Methods in a Node.js and Mongoose Application

In this section, we will discuss how to use instance methods in Mongoose to compare passwords using bcrypt. This approach is particularly useful for verifying user credentials during the login process. Here is the code for the instance method, followed by an explanation of how it works:

```
UserSchema.methods.comparePassword = async function (mainpassword) {
  return await bcrypt.compare(mainpassword, this.password);
};
```

###Explanation

**Instance Method Definition**

- _UserSchema.methods.comparePassword_: This line defines a new instance method called comparePassword on the Mongoose schema UserSchema. Instance methods are functions that operate on individual documents  _instances_ of the model.

**Async Function**

-  _async function (mainpassword) { ... }_ : The method is defined as an asynchronous function that takes mainpassword as an argument. mainpassword represents the plain text password that needs to be compared with the stored hashed password.

**Password Comparison**

- _return await bcrypt.compare(mainpassword, this.password);_ : This line uses bcrypt  compare function to compare the provided plain text password **mainpassword** with the hashed password stored in the current document **this.password** . The compare function returns a promise that resolves to true if the passwords match and false otherwise.

##Password Verification in Node.js Using Bcrypt with Mongoose Instance Methods

In this section, we will focus on how to use the **comparePassword** instance method within the login logic of a Node.js application to securely verify user passwords using bcrypt. Please note that the validation and error handling in this example are not the primary focus and are included for completeness.

```
const login = async (req, res) => {
  const { email, password } = req.body;

  //   validation
  if ((!email, !password)) {
    throw new BadRequestError("Please provide email and password");
  }

  const userLogin = await UserModel.findOne({ email });

  if (!userLogin) {
    throw new UnauthenticatedError("Invalid credentials");
  }

  const isPasswordCorrect = await userLogin.comparePassword(password);

  if (!isPasswordCorrect) {
    throw new UnauthenticatedError("Invalid credentials");
  }

  const token = userLogin.createToken();
  res
    .status(StatusCodes.OK)
    .json({ user: { name: userLogin.getName() }, token });
};
```

###Explanation of comparePassword Usage

**Finding the User**

- The code first retrieves the user document from the database using `UserModel.findOne({ email })`

- If the user is not found, it throws an error indicating invalid credentials.

**Comparing Passwords**

`const isPasswordCorrect = await userLogin.comparePassword(password);`

- This line uses the **comparePassword**  instance method defined on the user schema.

- The method compares the provided plain text password **password**  with the hashed password stored in the database _userLogin.password_ .

- _comparePassword_  uses _bcrypt_  compare function/method and returns true if the passwords match, or false otherwise.

**Handling Incorrect Passwords**

- If the password comparison fails  _!isPasswordCorrect_ , an error is thrown indicating invalid credentials.

**Generating and Returning a Token**

- If the password comparison succeeds, a token is generated using _userLogin.createToken()_

- The response includes the user name and the generated token

##Conclusion

In this article, we explored how to use [bcrypt](https://www.npmjs.com/package/bcrypt) in a [Node.js](https://nodejs.org/en) application with [Mongoose](https://mongoosejs.com/) to securely hash and verify passwords. We covered the installation of [bcrypt](https://www.npmjs.com/package/bcrypt), the implementation of password hashing using [Mongoose](https://mongoosejs.com/) pre save middleware, and the use of [Mongoose](https://mongoosejs.com/) instance methods for password comparison during login. By following these steps, you can enhance the security of your application authentication system, ensuring that user passwords are properly protected. 

![Happy Coding](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54ytgodi9v7ydrwanpsu.jpg)