This guide is to assist struggling programmers step through their own implementation of bcrypt with Node.js Since the genesis of the internet, salting and hashing an important piece of information has been one of the most crucial components towards having a secure site.

While there are many different ways to salt and hash data, using bcrypt is among the easiest methods.

Implementing bcrypt for a synchronous usage is almost too easy, but for an asynchronous usage, there can be an issue.

Asynchronous implementation

When utilizing a promise, from the server, following the documentation’s example will not work, due to the fact that it is expecting a promise from the database-side.

The solution that I was able to conceive was to use ‘Q’. Which is one of the many tools that is used to create and compose asynchronous promises. Implementing ‘Q’ with bcrypt turned out to be quite simple. First, you install the module using

npm install Q

Secondly, you declare a salt-factor, which will be used when generating salt. Higher the number, the larger the salt will be.

var salt_factor = 10;

Then you require the module where the insertion/query is made, by doing

var Q = require('q');

Creating a new user

When you are inserting a user’s credentials, before salting and hashing takes place, you declare a variable that will handle the deferment.

var defer = Q.defer();

After that, you salt and hash the user’s password by following the example from the bcrypt documentation.

var bcrypt = require('bcrypt');
bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash('B4c0/\/', salt, function(err, hash) {
        // Store hash in your password DB.
    });
});

The issue that I faced while following the example was that I the function itself, could not be used with a .then() or a return statement.

Here's my implementation of creating a user
exports.createUser = function(obj) {
    var defer = Q.defer();
    Bcrypt.genSalt(Salt_Factor, function(err, salt) {
        if (err) {
            return console.error(err);
        }
        Bcrypt.hash(obj.password, salt, function(err, hash) {
            if (err) {
                return console.err(err);
            }
            obj.password = hash;
            var user = new User(obj);   //Model instatiation using Mongoose
            user.save(function(err, user) {   //Inserting the model
                if (err) {
                    defer.reject(err);     
                } else {
                    defer.resolve(user);
                }
            });
        });
    });
    return defer.promise;
};
Checking a user's password

Similar to the example above, when checking a user’s credentials to the ones stored in your database, you use the .compare method instead of the .genSalt and .hash.

exports.findUser = function(obj) {
    var defer = Q.defer();
    User.find({ username: obj.username }).then(function(user, err) { //query method for Mongoose
        if (err) {
            console.log('unable to find user!!', err);
        } else {
            Bcrypt.compare(obj.password, user[0].password, function(err, result) {
                if (err) {
                    defer.reject(err);
                } else {
                    defer.resolve(result);
                }
            });
        }
    });
    return defer.promise;
};

Notice how defer.promise is returned in both of the examples at the end of the function body. By returning defer.promise outside of the invocation of bcrypt methods, from the server, the .then() promise can be utilized.

Example of a request handler using express
app.post('/createUser', function(req, res, next) {
    db.createUser(req.body).then(function(user, err) {
        if (err) {
            res.status(406);
        } else {
            res.status(200);
        }
    });
});