Remote Authentication Using JSON WEB TOKEN

Remote Authentication Using JSON WEB TOKEN

Check the source-code here.

Authentication is an important portion for web application. From client side, like a mobile application must require a secure authentication to the server and *passport is a prominent helper. Let’s find another [JSON Web Token](* package, that is totally session based authentication.

Here I’m developing simple Node API that is going to create dummy users and also using tokens to authenticate the users from remote client.


  • Two user routes will be available

  • One is not protected, going to create a user

  • Another is protected, send all the current users on request

  • Also one authentication request, response will be in JSON format with a new token


  1. Unit Testing using *mocha.js and [should.js(Assertion Library)](*

  2. API Testing via *POSTman*


  1. *Node.js(7.1.0)*

  2. *NPM(3.10.9)*

  3. *Express.js(4.15.2)*


First create the following project architecture…



This is a production ready application, we separated the developers dependencies and the main dependencies. Here’s the package.json file…

  **"name"**: **"jwt-auth"**,
  **"main"**: **"server.js"**,
  **"scripts"**: {
    **"start"**: **"node server.js"**,
    **"test"**: **"mocha --recursive **/test/runner.js"
  **"dependencies"**: {
    **"body-parser"**: **"^1.17.1"**,
    **"express"**: **"^4.15.2"**,
    **"express-session"**: **"^1.15.2"**,
    **"jsonwebtoken"**: **"^7.4.0"**,
    **"mongoose"**: **"^4.9.8"**,
    **"morgan"**: **"^1.8.1"
  **"devDependencies"**: {
    **"babel-eslint"**: **"^7.2.3"**,
    **"cors"**: **"^2.8.3"**,
    **"mocha"**: **"^3.3.0"**,
    **"mocha-logger"**: **"^1.0.5"**,
    **"nodemon"**: **"^1.11.0"**,
    **"should"**: **"^11.2.1"


  • We named our main server as server.js

  • Since we use *nodemon* for run the app, add the scripts to automate restart the server while a file is changed.

  • For automate testing purpose all the runner.js file will be fired recursively if that is exist under the test directory.

  • *body-parser* will grab the parameter on Post request.

  • *express* is the server side framework.

  • *express-session* is the session handling middle-ware.

  • *jsonwebtoken* for generate and verify the token

  • *mongoose* is the driver to interact with the mongoDB database.

  • *morgan* is a logger middle-ware for express framework.

  • *babel-eslint* for ECMA-Script 6 watcher.

  • *cors* for filter the clients.

  • *mocha* for Unit Testing in Node.js app.

  • *mocha-logger* for logging the unit test status.

  • *should* for assertion library


Go to the project folder and run

npm install

This will install all the package files in your project folder.

Now setup the server.js file …

**var **express = require(**'express'**);
**var **app = express();
**var **bodyParser = require(**'body-parser'**);
**var **logger = require(**'morgan'**);
**var **mongoose = require(**'mongoose'**);

**var **session = require(**'express-session'**);

**var config **= require(**'./config'**);

**var **router = require(**'./app/routes'**);

**var **port = process.**env**.PORT || 3000;
mongoose.connect(**config**.database.**db**, (err) => {
    **if**(err) {
        **console**.log(**'Error in connecting database : ' **+ **config**.database.**db **+ **" Error: " **+ err);
        res.send(500, {**err**: err});

app.set(**'superSecret'**, **config**.database.**mySecret**);

app.use(bodyParser.**urlencoded**({**extended**: **false**}));


app.use(**'/api'**, router);

**console**.log(**'Server running on port: ' **+ port);

Nothing special. Also setup the Database Configuration config/index.js

**var **db = {
  **db**: **'localhost:27017/jwtTokenAuthentication'**,
  **dbTest**: **'localhost:27017/jwtTokenAuthenticationTest'**,
  mySecret: **'Eminem'

module.exports = {
    **database**: db

One database for real data, another for testing purpose, I don’t want to messed up with the actual data while testing the application.


In your app/routes/index.js file …

**var **base = process.**env**.PWD;
**var **express = require(**'express'**);
**var **router = express.Router();
**var **userController = require(base + **'/app/controllers/userController/user'**);
**var **authenticateController = require(base + **'/app/controllers/authenticationController/authenticate'**);

router.get(**'/users'**, authenticateController.checkAuthentication, userController.getUsers);
router.**post**(**'/user'**, userController.createUser);
router.**post**(**'/authenticate'**, authenticateController.authenticateUser);

module.exports = router;

Here exists 3 routes,

  • One for get all the users, that will invoke getUsers method from the userController Object, also verify the token

  • Another for create the users, that will invoke createUser Method form userController object.

  • The third one is to authenticate the user by creating a json token.

    Get Users is protected by the token here


Two user controllers method placed here, one for create user and another for get the list of the users.

Put these code in app/controllers/userController/user/index.js

**var **base = process.**env**.PWD;
**var **User = require(base + **'/app/models/userModel'**);

var createUser = (req, res) => {
    var user = new User(req.body);, user) => {
        if(err) { res.send(500, {err: err}) }
        else { res.send(200, user); }

var getUsers = (req, res) => {
    User.find({}, (err, users) => {
        if(err) { res.send(500, {err: err}) }
        else { res.send(200, users); }

module.exports = {


The authentication controller has the job to generate and verify the token. These code go into app/controllers/AuthenticateController/authenticate/index.js

**var **base = process.**env**.PWD;
**var **jwt = require(**'jsonwebtoken'**);
**var **User = require(base + **'/app/models/userModel'**);
**var **config = require(base + **'/config'**);

var authenticateUser = (req, res) => {
    User.findOne({name:}, (err, user) => {
        if(err) { throw err; }
        if(!user) {
            res.send(500, {
                success: false,
                message: 'Authentication failed: User not Found'
            res.json(500, {
                success: false,
                message: 'Authentication failed: User not Found'
        } else if(user.password != req.body.password) {
            res.send(500, {
                success: false,
                message: 'Authentication failed: Password dose not match'
        } else {
            var token = jwt.sign(user, config.database.mySecret, {
                expiresIn: 1440  //24 hours
            res.send(200, {
                success: true,
                message: 'Token Created !!!',
                token: token

var checkAuthentication = (req, res, next) => {
    var token = req.body.token || req.query.token || req.headers['x-access-token'];
    if(token) {
        jwt.verify(token, config.database.mySecret, (err, decoded) => {
            if(err) {
                return res.json({
                    success: false,
                    message: 'Failed to authenticate token'
            } else {
                req.decoded = decoded;
    } else {
        return res.status(403).send({
            success: false,
            message: 'No Token Provided'

module.exports = {


Though database schema is not required mongoDB, for simplicity a simple schema will be defined. Only name, password and administrative status will be used here. To keep things simple password encryption is skipped. You must use some tools to encode and decode the password in production.

So database schema goes to app/models/userModel/index.js

**var **mongoose = require(**'mongoose'**);
**var **Schema = mongoose.Schema;
mongoose.**Promise **= global.*Promise*;

var userSchema = new Schema({
    name: { type: String, Required: true},
    password: { type: String, Required: true},
    admin: { type: Boolean, Required: false, default: false}

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

For details about the database schema, I recommend the *documentation*.


If everything is Ok, then run



node server.js

In if you are done accurately, the console should display

Server running on port 3000

Now your app is running. I would recommend to use nodemon to run the server.


For test purpose: authentication, getUsers and createUser will be tested in postMan. It’s the moment of truth :(

Create User

For creating an user we must provide the name and password.

  • Address should be http://localhost:3000/api/user

  • Set headers ‘content-type’ : ‘application/x-www-form-urlencoded’

  • In body mark x-www-form-urlencoded

  • Set value testName for name and testPassword for password.

In return you must get the created user information.

Authenticate User

To get authentication, the user have to provide the correct name and password. On success, the authenticate user would receive a token.

  • Address should be http://localhost:3000/api/authenticate

  • Set headers ‘content-type’ : ‘application/x-www-form-urlencoded’

  • In body mark x-www-form-urlencoded.

  • Set value testName for name and testPassword for password.

Get Users

Time to use our retrieved token. The retrieved token can be passed through the address parameter or headers or query. If the token is verified then we will get all the created users information.

  • Address should be http://localhost:3000/api/users

  • Set headers ‘content-type’ : ‘application/x-www-form-urlencoded’, ‘x-access-token’: ‘retrieved token’

Now all the users should be appeared in json format. In this case only one user exist. But try to create several users and check the list.

I won’t go deep on Unit Testing the app. Check my source to ensure testing. Run the following command to test the app. Add a test helper in Test/utils.js

var responseValidatorAsync = (expectedStatusCode, validationFunction) => {
    return {
        json: (statusCode, data) => {
        send: (statusCode, data) => {

module.exports = {

Also Unit test in the user Controller in app/controllers/userController/test/runner.js

process.**env**.**NODE_ENV **= **'test'**;

**var **base = process.**env**.PWD;
**var **config = require(base + **'/config'**);
**var **logger = require(**'mocha-logger'**);
**var **mongoose  = require(**'mongoose'**);
**var **User = require(base + **'/app/models/userModel'**);
**var **userController = require(base + **'/app/controllers/userController/user'**);
**var **should = require(**'should'**);
**var **testUtils = require(base + **'/Test/utils'**);

describe(**'API TESTING'**, () => {
    **var **id, dummyUser, userToken;

    **before**((done) => {
        mongoose.connect(config.database.**dbTest**, (err, user) => {
            **if**(err) { logger.*log*(**'Error in connecting database: ' **+ err) }
            **else **{ done(); }

        dummyUser = **new **User({
            **'name'**: **'dummyName'**,
            **'password'**: **'dummyPassword'
        **});, user) => {
            **if**(err) { logger.*log*(**'Error in saving user: ' **+ err); }
            **else **{ id = user._id; }


    describe(**'CREATE USER'**, () => {
        it(**'should create a new user'**, (done) => {
            **var **req = {
                **body**: {
                    **'name'**:**'new user'**,
                    **'password'**: **'new password'
            **var **res = testUtils.*responseValidatorAsync*(200, (user) => {
                user.**name**.should.equal(**'new user'**);
            userController.*createUser*(req, res);

    describe(**'GET ALL USERS'**, () => {
        it(**'should get all the users'**, (done) => {
            **var **req = {};
            **var **res = testUtils.*responseValidatorAsync*(200, (users) => {
            userController.*getUsers*(req, res);

    **after**((done) => {
        User.remove({}, (err) => {
            **if**(err) { logger.*log*(**'Error in removing all users from database: ' **+ err); }

To run the Unit Test

npm test

Voila, test result will be displayed in the terminal.


Hope you got an idea about the remote authentication using JSON WEB Token. Also check the source code *here. If there is anything about concept or the code response below or create an issue on [github](*.