A quick guide for Authentication using ‘bcrypt’ on Express/NodeJs
When I was in search of an answer to a simple yet comprehensive methodology of saving passwords on a local database, I found that there are many ways to do so.
The problem here was, how do I decide on choosing one of them when I have short deadlines and no time to trial and error? (think of a proof of concept code)
My choice of framework was ExpressJS (NodeJS) so, the first thing that stuck to me was to search packages on NPM for password-auth. There goes the solution to my problem. I stopped at ‘bcrypt’ and saw that the usage is simpler than all other methods online.
Here’s how to use it (async):
Step1: Make sure you have the appropriate dependencies installed and configured for your platform and then,
> npm install bcrypt
Step2: Declare a variable ‘saltRounds’
- With “salt round” they actually mean the cost factor. The cost factor controls how much time is needed to calculate a single BCrypt hash. The higher the cost factor, the more hashing rounds are done. Increasing te cost factor by 1 doubles the necessary time. The more time is necessary, the more difficult is brute-forcing.
- The salt is a random value, and should differ for each calculation, so the result should hardly ever be the same, even for equal passwords.
- The salt is usually included in the resulting hash-string in readable form. So with storing the hash-string you also store the salt.
- For a production ready code, do not settle for saltRounds less than 12.
var db = require('../models');var bcrypt = require('bcrypt');const saltRounds = 10;
Step3: Sign-up: Auto-generate a salt and hash
- Make a post route to create a new user during signup/register
- Pass the password entered by the user in the input field, saltRounds declared above and a callback function which returns err and hash.
- Now, store the values of name, email(and any other field that you want) entered in the input field, and password which is now the auto-gen hash value in the DB, by performing a Create operation (as shown in the example)
//register: storing name, email and password and redirecting to home page after signupapp.post('/user/create', function (req, res) { bcrypt.hash(req.body.passwordsignup, saltRounds, function (err, hash) {
db.User.create({ name: req.body.usernamesignup, email: req.body.emailsignup, password: hash }).then(function(data) { if (data) { res.redirect('/home'); } }); });});
Step4: Sign-in: To check for the correctness of password at Login
- Make a post route to verify the user during Sign-in
- Performing a findOne operation on User model(Select/Read operation) to find a user with matching/existing email of that entered in the input field.
- Write a promise (.then) function with the fetched user and verify if the email exists in DB already
- If no user exists, redirect to login/signup page to start over again
- If match found, compare with stored password, using the bcrypt.compare function.
- Pass the password entered by the user in the input field, the hashed password stored in DB in Step3 and a callback function which returns err and result.
- If the result of comparison is true, redirect to home page => Successful Login!
- If not, password is incorrect =>redirect to login/signup page to start over again
//login page: storing and comparing email and password,and redirecting to home page after login app.post('/user', function (req, res) { db.User.findOne({ where: { email: req.body.email } }).then(function (user) { if (!user) { res.redirect('/'); } else {bcrypt.compare(req.body.password, user.password, function (err, result) { if (result == true) { res.redirect('/home'); } else { res.send('Incorrect password'); res.redirect('/'); } }); } });});
Ignore my trial and error console logs :P
Example User Model for Sequelize with functions to generate hash and check validity of password
If you are working on a real world NodeJS application, please consider reading this article before you go any further !!
https://hackernoon.com/your-node-js-authentication-tutorial-is-wrong-f1a3bf831a46