User authentication using Json Web Token in nodejs

Hey all, today we are going to learn about the emplimentation of json web token in nodejs. And also explain in detail what JSON Web Token is and how it can be userd for the user authentication.

Lets understand the basic detail of JWT

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

JSON Web Tokens consist of three parts which contains encoded data, separated by dots (.), which are:

  • Header
  • Payload
  • Signature

Therefore, a JWT typically looks like the following.

aaaaaa.xxxxxx.iiiiiiiiiii

How JSON Web Token actually works for User Authentication

  • JWT is a stateless authentication mechanism where user’s state is never saved anywhere in the server. The server will check for a valid JWT in the Authorization header, and if it’s present, the user will be allowed to access protected resources. JWT  contains all the information within itself.
  • JWT fully rely on data APIs that are stateless . It doesn’t matter which different domains are serving our APIs so Cross-Origin Resource Sharing (CORS) won’t be an issue as it doesn’t use cookies.
  • Normal working flow in any application,  when user logins using valid credentials then server returns a JSON Web Token which contains its validity and all information itslelf. So for all further API jwt is passes as a header param in any API. If jwt autheticates successfully then request completes otherwise error throws in response.

Now lets discuss the emplimentation in our nodejs app.

package.json

 
{
"name": "jwt-authentication",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "Suraj Roy",
"license": "ISC",
"dependencies": {
"async": "^2.6.0",
"bluebird": "^3.5.1",
"body-parser": "^1.18.2",
"cookie-parser": "^1.4.3",
"crypto": "^1.0.1",
"express": "^4.16.2",
"express-session": "^1.15.6",
"httpstatuscode": "0.0.2",
"jsonwebtoken": "^8.1.0",
"md5": "^2.2.1",
"mongoose": "^4.13.7",
"mongoose-unique-validator": "^1.0.6",
"morgan": "^1.9.0"
}
}
 

 

In the above file we have our basic dependencies of the demo which we are going to create . Now we will set up our mongodb set up, so let's have a look on db config file

 
var mongoose = require('mongoose');
    dbconfig = require('./config')['dbconfig'];
 
let connection;
    var config = dbconfig['development'];
    connection = mongoose.connect(`mongodb://${config.database.HOST}:${config.database.MONGO_PORT}/${config.database.MONGO_DB}`);
 
module.exports = connection;
 

 

In the above file we have set up the db config.

Now let's discuss the routing part where authentication related task performs:

routes/apiRoutes.js

 

 
const express = require('express'),
    router = express.Router(),
    secretkey = require('../config/config')["secretkey"];
 
const appRoutes = {
    publicRoutes: ["/users/login","/users/sign-up", "/users/verify-otp"],
    userRoutes: ["/users/complete-profile"]
}
 
// Function to upload project images...
router.use(function (req, res, next) {
 
    if (appRoutes.publicRoutes.indexOf(req.url) >= 0) {
        next();
    } else
        var token = req.body.token || req.query.token || req.headers['x-access-token'];
        if (token) {
            jwt.verify(token, secretkey, function (err, decoded) {
                if (err) {
                    return res.json({ success: false, error_code: 406, message: 'Failed to authenticate token.' });
                } else {
                    req.decoded = decoded;
                    next();
                }
            });
        } else {
            return res.status(403).send({
                success: false,
                message: 'No token provided.',
                error_code: 406
            });
        }
    }
})
 
router.use("/users", require('../controller/user'));
 
module.exports = router;
 

 

In  the above file we have set the authentication related task, And in the constant appRoutes we have two keys, first public routes in which we pass the api methods which don;t need any authentication and in the second key userRoutes we have stored the name of apis which needs the authentication. And below jwt authentication works accoringly so that jwt will be checked in apis which are stored under userRoutes key.

These were the main points regarding the JSON Web Token, full working source code can be downloaded from this site. Let's have a look how we can check the emplimentation in  the api with the screenshots of postman.

1.  sign-up(header passed in below api [Content-Type:application/json])

User has been registered successfully.  Now come to the next step where user will login to get the JSON Web Token(header passed in below api [Content-Type:application/json]).

login-screenshot

In the above screenshot we can see token has been returned from the login API. Now in the next api  where jwt is authenticated to complete the request.( header passed in below api [Content-Type:application/json,
x-access-token:*************************])

complete profile

Pretty cool! Finally, our task completes here.

That’s all for now. Thank you for reading and I hope this post will be very helpful.

Let me know your thoughts over the email demo.jsonworld@gmail.com. I would love to hear them and If you like this article, share with your friends.

 

You can download complete code from here. Download Code