Search

Hash Password with Bcrytp in NodeJs

post-title

In this tutorial, we will learn to use NPM bcryptjs library to hash and compare the passwords in Node.

To create a secure application, it is always considered a safe practice not to store a user’s password in the database in plain text format. If not in plain text format, then what else we can do?

Here is the solution, generate a hash (complex string and numbers) and store that hash in the database. You can decipher your hashed password later by using the comparing method.

Let’s assume if there was a breach in your database, and all your stored passwords were leaked. Then, you are at significant risk, and password hashing is the best one-way encryption technique to secure the passwords.

In this method, you do not store users’ passwords in the database in its original form. Instead, a password is stored in a complex combination of text and unique characters; this is known as a password hash method.

A hacker can not easily decipher an adequately hashed password. Hackers will get frustrated because it will take lots of time and effort to decrypt the password.

In this tutorial, we will learn how to install and correctly hash a password in node.js.

We will take the help of the NPM BcryptJs package, and it is a widely used encryption module available nowadays via NPM.

Before we begin, you must have Node.js configured in your machine. If not, then you can check out how to install Node in your system tutorial.

Install bcryptjs Npm Module

To get started i assume you already have a Node.js project setup along with Express, and MongoDB.

Run one of the command based on your package manage.

# npm
npm install bcryptjs --save
 
# yarn
yarn add bcryptjs

Now, once bcryptjs successfully installed. We are ready to go ahead!

Hash A Password with Bcrytp Js

To get started with hashing the password we need node server configuration. In the app.js file, we imported express, bodyParser, mongoose and bcrytpjs module. We defined the MongoDB database connection, user schema and two REST APIs for registering and signing in the user.

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const bodyParser = require('body-parser');

// Express APIs
const api = require('./routes/auth.routes');

// MongoDB conection
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost:27017/nodedb", {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log('Database connected')
},
    error => {
        console.log("Database can't be connected: " + error)
    }
)

// Express settings
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(cors());

app.use('/api', api)

// Define PORT
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
    console.log('Connected to port ' + port)
})

// Express error handling
app.use((req, res, next) => {
    setImmediate(() => {
        next(new Error('Something went wrong'));
    });
});

app.use(function (err, req, res, next) {
    console.error(err.message);
    if (!err.statusCode) err.statusCode = 500;
    res.status(err.statusCode).send(err.message);
});

Hashing a password is very simple, the first argument in the bcrypt.hashSync() method is the password which we are getting from req.body middleware. The second argument is the number of rounds which we set to 10 to generate a salt.

// routes/auth.routes.js

const express = require("express");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const router = express.Router();
const userSchema = require("../models/User");


// Sign-up
router.post("/signup", (req, res, next) => {
    bcrypt.hash(req.body.password, 10).then((hash) => {
        const user = new userSchema({
            name: req.body.name,
            email: req.body.email,
            password: hash
        });
        user.save().then((response) => {
            res.status(201).json({
                message: "User successfully created!",
                result: response
            });
        }).catch(error => {
            res.status(500).json({
                error: error
            });
        });
    });
});

So we are hashing the password when the user makes the signup call after that we are creating a user instance and saving the user data along with the password in the MongoDB database.

Verify or Compare The Password with Bcrypt

When the user logs in the app, API will check the if the email exists in the database with the help of userSchema.findOne() method. Then, we will validate the stored password with the help of bcrypt.compareSync() method. It takes two passwords as an argument stored password and user-entered password.

// routes/auth.routes.js

const express = require("express");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const router = express.Router();
const userSchema = require("../models/User");


// Sign-in
router.post("/signin", (req, res, next) => {
    let getUser;
    userSchema.findOne({
        email: req.body.email
    }).then(user => {
        if (!user) {
            return res.status(401).json({
                message: "Authentication failed"
            });
        }
        return bcrypt.compare(req.body.password, user.password);
    }).then(response => {
        if (!response) {
            return res.status(401).json({
                message: "Authentication failed"
            });
        }
    }).catch(err => {
        return res.status(401).json({
            message: "Authentication failed"
        });
    });
});

i hope you like this article.