Authentication

Authentication

LEVEL 1

<aside> 💡 LEVEL 1

In this level the data is stored in MongoDB.

</aside>

Step 1) Connect to database.

mongoose.connect("mongodb://localhost:27017/userDB");        

Step 2) define schema.

const userSchema = new mongoose.Schema({
    	email: String,
    	password: String
	});        

Step 3) Define model

const User = new mongoose.model("User", userSchema);        

Step4) Register a new user

app.post('/register', function(req, res){
    const newUser = new User({
        email: req.body.username,
        password: req.body.password
    });
    newUser.save(function(err){
        if(err){
            console.log(err);
        } else {
            res.render('secrets');
        }
    });
});        

Step 5) Code to verify user in login page.

app.post('/login', function(req, res){
    const username = req.body.email;
    const password = req.body.password;
    User.findOne({email: username}, function(err, foundUser){ 
        if(err){
            console.log(err);
        } else {
            if(foundUser){
                if (foundUser.password === password){
                    res.render('secrets');
                }
            }
        }
    });
});        

<aside> 📌 SUMMARY: In Level 1 the email and password is not encrypted hence the database can be hacked easily and is not so secure. Hence moving on to LEVEL 2.

</aside>

LEVEL 2

<aside> 💡 LEVEL 2

In this level the data is stored in MongoDB ie password and email are encrypted.

Using NPM package called mongoose-encryption.

</aside>

mongoose-encryption

Refer above link to know more about mongoose-encryption package.

Mongoose Encryption package encrypts data when it is saved into database and decrypts when find method is called data will automatically be decrypted.

Step 1) Install Package and call the function.

install mongoose encryption package.

npm i mongoose-encryption
const encrypt = require('mongoose-encryption');        

Step 2) Define a constant secret variable.

Secret String Instead of Two Keys

For convenience, you can also pass in a single secret string instead of two keys.

const secret = "Thisismysecretwhichnooneshouldknow";        

Step 3) Encrypt the user data with secret key.

Rest of the code in Level 2 remains same as the mongoose encryption package encrypts when

save() method is called and decrypts when find() method is called.

userSchema.plugin(encrypt, { secret: secret , encryptedFields: ["password"] });        

Using Environment variables to keep Secrets safe

When the above code is uploaded to Github it can be easily misused by Hacker to secure the code by using dotenv package from npm.

Step 4) Install dotenv package

npm i dotenv        

Import and configure dotenv

require('dotenv').config()        

Create a .env file in the root of your project:

touch .env        

In .env file some indentations are to be followed

S3_BUCKET="YOURS3BUCKET"
SECRET=Thisisourlittlesecret.        

Assigning secret variable from .env file

const secret = process.env.SECRET;        

<aside> 💡 Now that secret is written in .env file how to not upload it to GIthub.

</aside>

Simple add .gitignore file and add this folder name in that ……Simple !

<aside> 📌 SUMMARY: In Level 2 the password is encrypted hence the database when hacked cannot be easily decrypted, but still it is not that secure. Hence moving on to LEVEL 3.

</aside>

LEVEL 3

<aside> 💡 LEVEL 3

In this level the Password is encrypted with Hash function.

This can be done using npm package called md5

</aside>

md5

For more information refer above link.

Step 1) Install the package and call the function

npm install md5
const md5 = require('md5');        

Step 2) Encrypting password with hash function

app.post('/register', function(req, res){
    const newUser = new User({
        email: req.body.username,
        password: md5(req.body.password)
    });
    newUser.save(function(err){
        if(err){
            console.log(err);
        } else {
            res.render('secrets');
        }
    });
});        
Once the password is encrypted with hash function it cannot be decrypted by any chance i.e it is very difficult to do so.

Step 3) To match the password when user login

In Step 2 password is encoded at register level to verify the user we cannot decrypt it so we just encrypt the user entered password at login page also and match them.

app.post('/login', function(req, res){
    const username = req.body.email;
    const password = md5(req.body.password);
    User.findOne({email: username}, function(err, foundUser){ 
        if(err){
            console.log(err);
        } else {
            if(foundUser){
                if (foundUser.password === password){
                    res.render('secrets');
                }
            }
        }
    });
});        

<aside> 📌 SUMMARY: In Level 3 Password is encrypted using HASH function which has no key. But there is one problem simple passwords can be easily matched and can be determined. Hence Moving on to LEVEL 4.

</aside>

LEVEL 4

<aside> 💡 LEVEL 4

In this level the Password is encrypted with Bcrypt function.

This can be done using npm package called bcrypt. Bcrypt is slow in generating number of hashes per second which gives a major head blow when hacker tries hacking our passwords.

</aside>

bcrypt

A salt is a random string that makes the hash unpredictable. Bcrypt is a popular and trusted method for salt and hashing passwords.

Step 1) Setting up Node version and Bcrypt=

curl -o- <https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh> | bash
nvm --version
nvm install <latest version of node>    <-- Example -->
nvm install 16.17.0
npm i bcrypt        

If you get any errors or warnings checkout above link it has Github repo link there in issues you can find a solution for your problem.

npm install --force --global bcrypt@latest        

LEVEL 5

<aside> 💡 LEVEL 5

In this level the Password is encrypted with passport and many packages.

In this level cookies are also being created to ensure that logged in user may not need to login again and again.

</aside>

passport

passport-local

passport-local-mongoose

express-session

Install necessary packages

npm i passport passport-local passport-local-mongoose express-session        

Initialise the packages installed in app.js

const session = require('express-session')
const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose');
app.use(session({
    secret: "Our little secret.",
    resave: false,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());        

Initialise plugin for user to create cookies

mongoose.connect("mongodb://localhost:27017/userDB");
const userSchema = new mongoose.Schema({
    email: String,
    password: String
});

userSchema.plugin(passportLocalMongoose);

const User = new mongoose.model("User", userSchema);
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());        

To authenticate user in register page

Syntax

User.register({username:'username', active: false}, 'password', function(err, user) {
  if (err) { ... }

  const authenticate = User.authenticate();
  authenticate('username', 'password', function(err, result) {
    if (err) { ... }

    // Value 'result' is set to false. The user could not be authenticated since the user is not active
  });
});        

Example code

app.post('/register', function(req, res){
    User.register({username: req.body.username}, req.body.password, function(err, user){
        if(err){
            console.log(err);
            res.redirect('/register');
        } else {
            passport.authenticate("local")(req, res, function(){
                res.redirect('/secrets');
            });
        }
    });
});        

By using cookies we can check whether user has logged in or not

app.get('/secrets', function(req, res){
    if(req.isAuthenticated()){
        res.render('secrets');
    }else{
        res.redirect('/login');
    }
});        

In login route to verify user

app.post('/login', function(req, res){
    const user = new User({
        username: req.body.username,
        password: req.body.password
    });
    req.login(user, function(err){  
    if(err){
        console.log(err);
    } else {
        passport.authenticate("local")(req, res, function(){
            res.redirect('/secrets');
        });
    }
});        

Logout Route being Initialised

app.get('/logout',function(req,res){
    req.logout();
    res.redirect('/');
});        

To view or add a comment, sign in

More articles by Pushpakkumar B H

  • AWS Storage

    AWS storage services are grouped into three categories. File Storage In file storage, data is stored as files in a…

  • VPC

    Virtual Private Cloud Contents CIDR , Private IP and Public IP VPC Overview Subnet Internet Gateways and Route Table…

  • Application Programming Interface (API)

    Chapter 1 INTRODUCTION Application programming interfaces (API) simplify software development and innovation by…

Others also viewed

Explore content categories