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 logging. We will hash the password when the user registers, and then compare that password with the hash when they log in.
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 using a rainbow table, which you can counteract by applying salt to the hash before storing it.
Setup Project Folder
- Open the console and 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 set up.
- This will hold all the metadata related to our project.
Install Packages
About packages
- Express: It is a framework on which our application will be built.
- Body-parser: Extract the entire body portion of an incoming request stream and expose it on the req. body.
- 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.
- Bcryptjs: this is a Javascript library by which we can hash and compare passwords.
Create Model
- Create a new folder model and add the file user.js
- The user.js will contain the collection schema of our user.
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true
},
name: {
type: String
},
password: {
type: String
}
});
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(): The Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
Now we set our application start point
- Create a new file named app.js
- App.js
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var userModel = require('./models/users');
var bcrypt = require('bcryptjs');
mongoose.connect('mongodb://localhost:27017/bcrypt', { useNewUrlParser: true })
.then(function() {
console.log('connected to database');
})
.catch(function(error) {
console.log('error occured' + error);
});
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/register', function(req, res) {
try {
console.log(req.body);
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(req.body.password, salt, function(err, hash) {
var userr = new userModel({
email: req.body.email,
name: req.body.name,
password: hash
});
userr.save(function(err, data) {
if (err) {
console.log(err);
res.json({ er: err });
} else {
res.json({ da: data });
}
});
});
});
} catch (error) {
console.log(error);
res.json({ er: error });
}
});
app.post('/login', function(req, res) {
try {
userModel.find({ email: req.body.email }, function(err, data) {
console.log(data);
if (err) {
res.json({ er: error });
} else {
if (data) {
console.log('data' + data[0].password);
bcrypt.compare(req.body.password, data[0].password, function(err, result) {
if (err) {
res.json({ msg: 'email password doesnt matched.Try again!', er: err });
} else {
res.json({ da: result, msg: 'password matched' });
}
});
} else {
res.json({ msg: 'user doesnt exists' });
}
}
});
} catch (error) {
res.json({ er: error });
}
});
var port = process.env.PORT || 3000;
app.listen(port, function() {
console.log('server running at port ' + port);
});
- genSalt(): This will generate salt. Here we provide several rounds to use, which defaults to 10 if omitted.
- hash(): This will hash our password with the salt.
- compare(): Compares the given data against the given hash.
Click to watch the tutorial
Output
- Register user
- User login
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