REST service authentication using jsonwebtoken

In my last tutorial, we have gone through REST service creation using nodeJS and MongoDB. In this tutorial we will show, how to make token based authentication using jsonwebtokenwe will use mongodb for user login information.

Lets install the jsonwebtoken module using the following command:

npm install jsonwebtoken --save

"--save" option will add this module in package.json for future installation.

Now add this module to the server.js file in the following way:

jwt = require('jsonwebtoken'),

Now lets create a user model  so that we can verify user. Create a user.js file under app/models folder and put the following contents in it:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema;

var UserSchema = new Schema({
    name : String, 
    password : String, 
    admin : Boolean
})

module.exports = mongoose.model('User', UserSchema);

Now, let's proceed to the authentication process. Authentication consists of two steps:

  1. Login with Username and password
  2. verify the authentication before each request

To make the authentication we will create a Service called authentication.js under app/service folder and put the following code. FYI, this is modular class which will expose two methods. One for check login and another one for verify login before is each request.

var User = require('../../app/models/user'),
    jwt = require('jsonwebtoken'),
    auth = require('../../app/config/auth');

var authenticate = (function (){
    /**
     * @method checkLogin
     * @description check login with user name and password 
     */
    var checkLogin = function (username, password, response) {
        User.findOne({name : username}, function (err, user) {
            if (!user) {
                response.json({
                    success: false, 
                    message : 'Authentication failed. User not found'
                });
            } else if (user) {
                if (user.password != password) {
                    response.json({
                        success: false, 
                        message : 'Authentication failed. User/Password not found'
                    });
                } else {
                    var token = jwt.sign(user, auth.secret, {
                        expiresIn : 1440 // expires in 24 hours
                    });

                    response.json({
                        success: true,
                        message: 'Authentication Success! Enjoy your token',
                        token : token
                    });
                }
            }
        });
    };

    return {
        checkLogin : checkLogin
    };

}());

module.exports = authenticate;

To verify the login before each request, we need to have a method first. Create the following method inside the authenticate module in the following way:

.......................................................................
/**
     * @method isLoggedin
     * @description check login with user name and password 
     */
    var isLoggedin = function (request, response, next) {
        var token = request.body.token || request.query.token || request.headers['x-access-token'];

        if (request.url === '/authenticate' || request.url === '/setup') { //if try to login, avoid token check
            next();
            return false;
        }
        
        if (token) {
            jwt.verify(token, auth.secret, function (err, decoded) {
                if (err) {
                    response.json({
                        success: false,
                        message : 'Failed to authenticate token'
                    });
                } else {
                    request.decoded = decoded;
                    next();
                }
            });
        } else {
            response.json({
                success: false,
                message : 'No toekn has provided'
            });
        }
    };
.......................................................................

Now expose this method as public in the following way:

.......................................................................
return {
        checkLogin : checkLogin,
        isLoggedin : isLoggedin
    };
.......................................................................

Now we have to update route.js file. We use the following route, which will verify the login, before serving the content to that particular request URL. To do that add the following code in route.js file:

var express = require('express'),
    Bear = require('../../app/models/bear'),
    User = require('../../app/models/user'),
    jwt = require('jsonwebtoken'),
    auth = require('../../app/config/auth'),
    authService = require('../../app/service/authenticate'),
    router = express.Router();

router.use(function(req, res, next){
    console.log('Something is trying to reach at ', req.url);
    authService.isLoggedin(req, res, next);
});

// make the authentication request
router.post('/authenticate', function (req, res) {
    authService.checkLogin(req.body.name, req.body.password, res);
});

//rest of code 
.......................................................................

Now try to get list of bear from GET http://www.localhost:8080/api/bears using postman

screen-shot-2016-10-19-at-8-29-57-pm

Now it will through an error because authentication token is not available. Now Lets login or authenticate a user and get the token. Check this :

screen-shot-2016-10-19-at-8-29-10-pm

Now copy the token and put it in the GET request header like this way:

screen-shot-2016-10-19-at-8-30-33-pm

Now you will see the list of bear because Authentication token was passed as an header.

Hope you enjoy the process step by step. More will be added soon....