Setting Up Token Based Authentication In Node JS Using Express Framework

Introduction
 
These days if you are looking to build web services then you need to implement authentication so that your data is secured. Authentication is one of the big parts of every application and it can save your data from being misused.

Security tokens are becoming a standard way of applying security to web apis. Applying token based authentication is fairly easy method as client just need to send security token with every request is made to server.

You can view entire source code on Github from here 
 
Software’s needed
  • Node JS - Platform
  • Postman – used for creating http requests like GET, PUT, POST, DELETE
  • Sublime/Notepad++ - IDE for writing code.
Installing dependencies
 
We will be using jsonwebtoken npm package for creating web token and for verifying the same for the subsequent requests.
 
We have also used morgan which will help you do logging on console and this will make us to easily see what is happening inside our node application.
  1. Npm install express sequelize body-parser jsonwebtoken morgan  
Setting up & Coding
  1. var express = require('express'),  
  2.     bodyParser = require('body-parser');  
  3.    
  4. var users = require('./users.json');  
  5. var logger = require('morgan');  
  6. var app = express();  
  7. app.use(bodyParser());  
  8. app.use(logger('dev'));  
  9. var port = 8080; //setting port no.  
  10. var jwt = require('jsonwebtoken');  
  11. app.set('superSecret'"success is inevitable");  
  12. var router = express.Router();  
We will add authentication as a middleware in our node.js application. This will allow middleware to process any request coming to our application before it is passed to any specific route to handle. Within our middleware we will checking for valid token and if it is present in http header, request will be passed on specific route to handle.
  1. router.post('/authenticate'function(req, res) { //this will issue token for valid users  
  2.     var username = req.body.user;  
  3.     var password = req.body.password;  
  4.     var isUserFound = false;  
  5.     var foundUser = {};  
  6.     console.log(req.body.user + " " + req.body.password);  
  7.     for (var i = 0; i < users.length; i++) {  
  8.         if (users[i].user === req.body.user) {  
  9.             isUserFound = true;  
  10.             foundUser = users[i];  
  11.         }  
  12.     }  
  13.     if (isUserFound) {  
  14.         if (foundUser.password == req.body.password) {  
  15.             var token = jwt.sign(foundUser, app.get('superSecret'), {  
  16.                 expiresInMinutes: 1440 // expires in 24 hours  
  17.             });  
  18.             console.log(token);  
  19.             res.json({  
  20.                 success: true,  
  21.                 message: 'Enjoy your token!',  
  22.                 token: token  
  23.             });  
  24.         } else {  
  25.             res.json({  
  26.                 success: false,  
  27.                 message: 'Authentication failed. Wrong password.'  
  28.             });  
  29.         }  
  30.         res.send(foundUser);  
  31.     } else {  
  32.         res.json({  
  33.             success: false,  
  34.             message: 'Authentication failed. user not found.'  
  35.         });  
  36.     }  
  37. });  
We have added localhost:8080/api/authenticate as a route where you can get secure token if you are having valid credentials. We will be sending this token in http header of our request. This token could be used for subsequent request made to our application. Our token has a expire time and it could be set within the application.
  1. [{  
  2.     "user""[email protected]",  
  3.     "password""test"  
  4. }, {  
  5.     "user""[email protected]",  
  6.     "password""vijay"  
  7. }]  
I have created a user.json in which I will keep our valid user & their passwords. We will be loading this file in the starting and consuming it in our application.
  1. //middleware  
  2. router.use(function(req, res, next) {  
  3.   
  4.     // check header or url parameters or post parameters for token  
  5.     var token = req.body.token || req.query.token || req.headers['x-access-token'];  
  6.   
  7.     // decode token  
  8.     if (token) {  
  9.         // verifies secret and checks exp  
  10.         jwt.verify(token, app.get('superSecret'), function(err, decoded) {  
  11.             if (err) {  
  12.                 return res.json({  
  13.                     success: false,  
  14.                     message: 'Failed to authenticate token.'  
  15.                 });  
  16.             } else {  
  17.                 // if everything is good, save to request for use in other routes  
  18.                 req.decoded = decoded;  
  19.                 next();  
  20.             }  
  21.         });  
  22.     } else {  
  23.         // if there is no token  
  24.         // return an error  
  25.         return res.status(403).send({  
  26.             success: false,  
  27.             message: 'No token provided.'  
  28.         });  
  29.     }  
  30. });  
If token will not be present or token is expired or token is not valid then we will get an error.
  1. router.get('/users'function(req, res) {  
  2.     //console.log(User);  
  3.     return res.json({  
  4.         status: 'OK',  
  5.         msg: "you are authenticated and all set to consume our services."  
  6.     });  
  7.    
  8. });  
  9. router.use(function(req, res, next) {  
  10.     // do logging  
  11.     console.log('Something is happening.');  
  12.     next();  
  13. });  
  14.    
  15. app.use('/api', router);  
  16.    
  17. // START THE SERVER  
  18. // =============================================================================  
  19. app.listen(port);  
  20. console.log('Magic happens on port ' + port);  
We have added a test route which will help us to check the api against localhost:8080/api/user endpoint.

Testing our application
 
1. We are not sending any token
 
 

2. We are sending valid user to fetch token at /api/authenticate.
 
Request http msg
 
 

Response http msg

 
 
3. Our token is valid and we our GET request fulfilled. Token is send in http header when we are making any request.