DEV Community

Cover image for Different ways for User Authentication & Authorization with NodeJS Part - 1
Lavish Goyal
Lavish Goyal

Posted on

Different ways for User Authentication & Authorization with NodeJS Part - 1

First let us get over with the debate of Authentication vs Authorization.

Authentication

It is the process to verify if the user is telling the truth. For example: when we log into our account with some username and password, the process of verifying those credentials with the stored information in database and knowing that the user is really whom he/she claims to be is called Authentication.

Authorization

It is a security process to know what information user has access to. Giving someone permission to download a particular file on a server or providing individual users with administrative access to an application are good examples of authorization.

In this article we are going to look into two different methods of User Authentication with NodeJS

  • Sesssion Based Authentication
  • Token Based Authentication

Prerequisites

  • NodeJS
  • MongoDB (You can use an Atlas account or local mongodb connection)

Setup a new NodeJS project using npm or yarn whatever you like.

Session Based Authentication

session-auth.png

This image very simply summarizes the session based authentication. Let's implement it in code and understand better.

Execute the following line of code on your terminal within your project directory.

npm install express express-session mongoose connect-mongo

express - For creating our server
express-session - For creating our session based authentication
mongoose - To Connect to our MongoDB Database
connect-mongo - For storing our sessions in MongoDB Database

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo');
const session = require('express-session');

await mongoose.connect('your_mongo_url', (err, db) => {
            console.log('MongoDB Connected....');
      });

app.get('/', (req,res)=>{
    res.send('<h1>Hello World!</h1>')  
})

app.listen(5000, () => console.log(`Server 🔥🔥🔥 up on 5000`));
Enter fullscreen mode Exit fullscreen mode

This block of code will make our server up and running on Port 5000. So if you now visit http://localhost:5000/ you will see the desired result.

Now let us configure the MongoDB Store for session storage.

app.use(session({
    secret: 'fiwafhiwfwhvuwvu9hvvvwv', // Never ever share this secret in production, keep this in separate file on environmental variable
    resave: false,
    saveUninitialized: true,
    cookie: { maxAge: oneDay },
    store: MongoStore.create({
        mongoUrl: 'your_mongo_url'
    })
}));
Enter fullscreen mode Exit fullscreen mode

This block of code used the express-session package to create an empty Session object for a request.
Refer to this link to understand about saveUninitialized and resave properties in the object.

So this will create a new empty session inside our mongodb database with a collection name sessions.

Let's create a login route for user

app.post('/login', async (req, res) => {
    const { username, password } = req.body;    
try {
        let user = await User.findOne({ email: username })
        req.session.userId = user.id;

        console.log(req.session);

        res.redirect('/dashboard')

    } catch (err) {
        console.log(err);
        res.json({ msg: 'Server Error! Please reload page' });
    }
})
Enter fullscreen mode Exit fullscreen mode

Now this block of code is important. Now when the user logs into its account with username and password we send that request to our server and store the request in the session. req.session.userId is storing the unique _id of the user in the session and server creates a unique session id which is placed in the cookie which will be sent back to the client and stored in the client's browser as. Now whenever the client will make any request to the server the header will contain this cookie and we at server side are able to authenticate that particular user using that cookie in the header and obtaining the userId of the user.

module.exports.authentication = async (req, res, next) => {
    const userId = req.session.userId;
    if (!userId) {
        return res.redirect('/login?q=session-expired');
    }
    try {
        let user = await User.findById(userId);
        if (!user) {
            return res.redirect('/login?q=session-expired');
        }
        next();
    } catch (err) {
        console.log(err);
        res.json({ msg: 'Server error. Please reload page after sometime' })
    }
};
Enter fullscreen mode Exit fullscreen mode

We can create this type of middleware function where for every request on protected routes like dashboard, booking history, payment routes etc we can authenticate the user and display the correct data according to the user.

Advantages of Session Based Authentication

  • Cookies are small-sized values, easy to use and implement and can revoke the validity of the cookies.

Disadvantages of Session Based Authentication

  • Sessions are stored in server/database and not on client side thus it makes it really difficult to scale the project when there is a huge number of requests simultaneously.

This is where token based authentication (a modern and scalable solution) comes in. It solves the biggest headache with the session authentication that tokens are stored in client's browser thus making it really simple to scale the application.
Stay Tuned for part 2 where we talk all about the Token Based Authentication.

Buy Me A Coffee

Discussion (4)

Collapse
quazywabbit1 profile image
QuazyWabbit

If you're enjoying express, I really recommend taking a look at nestjs!

Collapse
lavig10 profile image
Lavish Goyal Author

I will surely work with nestjs. Have heard a lot about it. Thanks for recommendation

Collapse
rossja profile image
Jason Ross

It looks like your login route never validates the password matched, it appears to simply find a match for the user email that was entered, meaning anyone that knows a valid user email would be able to login as that user regardless of what password they provide?

Collapse
lavig10 profile image
Lavish Goyal Author

Oh yes. While writing this article I forgot to mention the password match and password verification in the login route. Thanks for pointing it out.