Hashing Password With Bcrypt In Node

Introduction

 
In this article, we will be using the bcryptjs javascript library for hashing and comparing passwords. Here, we will build a simple API for registering and login. We will hash the password when the user registers, and then compare that password with the hash when they login.
 

What is bcrypt ?

 
bcrypt is a password hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function. Over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.
 

What is hashing? 

 
Hashing is a one-way function (well, a mapping). It's irreversible, you apply the secure hash algorithm and you cannot get the original string back. The most you can do is to generate what's called "a collision", that is, finding a different string that provides the same hash. Cryptographically secure hash algorithms are designed to prevent the occurrence of collisions. You can attack a secure hash by the use of a rainbow table, which you can counteract by applying a salt to the hash before storing it. 
 

Setup Project Folder 

  • Open the console type below command to make a new directory
    # mkdir bcrypt
  • Change to the new directory
    # cd bcrypt

Setup Node In Project

  • Now set up our workspace by using the below command:
    # npm init
  • This will generate the package.json file which states that the node is correctly setup.
  • This will hold all the metadata related to our project.

Install Packages

  • Now install packages that will be required in our project.
  • Type npm install followed by package name
    # npm install --save bcryptjs express body-parser mongoose
  • After installing packages, package.json will look like this 
Hashing Password With Bcrypt In Node
 

About packages

  1. Express - it is a framework on which our application will be built.
  2. Body-parser - extract the entire body portion of an incoming request stream and exposes it on req.body.
  3. Mongoose - Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js.It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB.
  4. Bcryptjs - this is a Javascript library by which we can hash and compare passwords.

Create Model

  • Create a new folder models and add the file user.js
The user.js will contain the collection schema of our user.
  1. var mongoose = require('mongoose');  
  2.   
  3. var userSchema = new mongoose.Schema({  
  4.     email:{  
  5.         type:String,  
  6.         unique:true  
  7.     },  
  8.     name:{  
  9.         type:String  
  10.     },  
  11.     password:{  
  12.         type:String  
  13.     }  
  14. });  
  15.   
  16. module.exports = mongoose.model('user',userSchema);  
  • mongoose.schema() - Everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.
  • mongoose.model() - Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
Now we setup our application start point 
  • Create a new file name it app.js
App.js
  1. var express     = require('express');  
  2. var bodyParser  = require('body-parser');  
  3. var mongoose    = require('mongoose');  
  4. var userModel   = require('./models/users');  
  5. var bcrypt      = require('bcryptjs');  
  6.   
  7. mongoose.connect('mongodb://localhost:27017/bcrypt',{useNewUrlParser:true})  
  8. .then(function(){  
  9.     console.log('connected to database');  
  10. }).catch(function(error){  
  11.     console.log('error occured'+error);  
  12. });  
  13.   
  14. var app = express();  
  15.   
  16. app.use(bodyParser.urlencoded({extended:false}));  
  17. app.use(bodyParser.json());  
  18.   
  19. app.post('/register',function(req,res){  
  20.     try {  
  21.         var x;  
  22.         console.log(req.body);  
  23.          bcrypt.genSalt(10,function(err,salt){  
  24.          bcrypt.hash(req.body.password,salt,function(err,hash){  
  25.          var userr = new userModel({  
  26.             email:req.body.email,  
  27.             name:req.body.name,  
  28.             password:hash  
  29.         });  
  30.         userr.save(function(err,data){  
  31.           if(err){  
  32.               console.log(err);  
  33.               res.json({er:err});  
  34.           }  
  35.           else{  
  36.               res.json({da:data});  
  37.           }  
  38.         });  
  39.      });  
  40.     });  
  41.     } catch(error){  
  42.         console.log(error);  
  43.          res.json({er:error});  
  44.     }  
  45. });  
  46. app.post('/login',function(req,res){  
  47.     try {  
  48.          userModel.find({email:req.body.email},function(err,data){  
  49.              console.log(data);  
  50.               if(err){  
  51.                   res.json({er:error});  
  52.               }else{  
  53.                   if(data){  
  54.                       console.log('data'+data[0].password);  
  55.                       bcrypt.compare(req.body.password,data[0].password,function(err,result){  
  56.                           if(err){  
  57.   
  58.                               res.json({msg:'email password doesnt matched.Try again!',er:err});  
  59.                           }  
  60.                           else{  
  61.                         res.json({da:result,msg:'password matched'});  
  62.                           }  
  63.                       });  
  64.                   }  
  65.                   else{  
  66.                       res.json({msg:'user doesnt exists'});  
  67.                   }  
  68.               }  
  69.          });  
  70.     } catch (error) {  
  71.         res.json({er:error});  
  72.     }  
  73. });  
  74.   
  75. var port = process.env.PORT || 3000;  
  76. app.listen(port,function(){  
  77.     console.log('server running at port '+port);  
  78. });  
  • genSalt() - This will generate salt .Here we provide number of rounds to use, defaults to 10 if omitted.
  • hash() - this will hash our paswword with the salt.
  • compare() - compares the given data against the given hash.
 

Output

  •  register user 
Hashing Password With Bcrypt In Node
  •  user login
Hashing Password With Bcrypt In Node
 
References
  • https://en.wikipedia.org/wiki/Bcrypt 
  • https://github.com/dcodeIO/bcrypt.js/blob/master/README.md 
  • https://mongoosejs.com/docs/index.html 
  • https://stackoverflow.com/questions/326699/difference-between-hashing-a-password-and-encrypting-it/326706#326706