How to Use Bcrypt for Password Hashing in Node.js
john mbugua
Posted on July 1, 2024
Page Content
- Introduction to Bcrypt
- Getting Started with Bcrypt
- Using Bcrypt with Mongoose Pre Save Middleware
- Implementing Password Comparison with Instance Methods in a Nodejs and Mongoose Application
- Password Verification in Nodejs Using Bcrypt with Mongoose Instance Methods
- 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
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 in a Node.js application with Mongoose to securely hash and verify passwords. We covered the installation of bcrypt, the implementation of password hashing using Mongoose pre save middleware, and the use of Mongoose 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.
Posted on July 1, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.