CleverStack – Token based authentication

To enable other sites to query your backend API created with Clever-Stack, here are a few steps to replicate in your code:

Step 1 – Add token to cors config of backend:

  • Browse to ./backend/config/ and open global.json
  • Add token key [“x-access-token”] to headers. Eg.: [ “x-requested-with”, “content-type”, “X-XSRF-TOKEN”, “x-access-token” ]

 

Step 2 – Add JSONWebToken to node_modules:

  • Browse to ./backend/ and open package.json
  • Add jsonwebtoken to dependencies array. Eg.: “jsonwebtoken”: “~1.1.1”,
  • In command line, navigate to ./backend folder, and run
npm install jsonwebtoken@1.1.1

Step 3 – Create extra service and controller in your backend module:

  • Browse to ./backend/modules/<your module to query> and expand your controllers and services folders, these should contain at least 1 file each
  • For demo purposes, I will use ite-help as my module.
  • Currently under controllers I have IteHelpController.js and under services IteHelpService.js
  • Under the services folder, create new js file. Eg.: HelpService.js
module.exports = function( Service, IteHelpModel ) {
    return Service.extend({
        model: IteHelpModel
    });
}
  • Under the controllers folder, create new js file. Eg. HelpController.js
module.exports = function( app, Controller, HelpService ) {
    return Controller.extend(
        /** @Class **/
        {
             service: HelpService,
        },
        /** @Prototype **/
        {
        });
}

Step 4 – Enable controller to validate token that will be sent from requesting site/domain:

  • Browse to ./backend/modules/<your module to query>/controllers/ and open <newly created js file>
  • At the top of controller, include jsonwebtoken. Eg.:
var jwt = require('jsonwebtoken');
  • In /** @Class **/ section of code, do the following:
  • Add autoRouting. Eg.:
autoRouting: [ 'authenticateToken' ],
  • Add function to handle the token authentication in /** @Class **/ section of code, in this case it is called authenticateToken
authenticateToken: function ( req, res, next ) {
    app.set('tokenSecret', '<some token secret>');
    app.set('tokenKey', '<some token key>');

    var token = (req.body && req.body.access_token) || (req.query && req.query.access_token) || req.headers['x-access-token'];

    if (token) {
        jwt.verify(token, app.get('tokenSecret'), function(err, decoded) {
            if (err) {
                res.send( 401 );
            } else {
                if ( decoded.token === app.get('tokenKey') ) {
                    next();
                } else {
                    res.send( 401 );
                }
            }
        });
    } else {
        res.send( 401 );
    }
}, //tested

Step 5 – Generate token key, secret and jwt tokens:

  • Sites used to generate the key and then hash it.

Site 1: http://online-code-generator.com/generate-salt-random-string.php

Site 2: http://www.convertstring.com/Hash/SHA512

  • From site 1, generate strong salted string, copy this and go to site 2 and hash the copied string.
  • Copy hashed string and replace either the token secret or token key with this value.
  • Repeat top 3 steps until both token secret and token key have hashed strings.
  • Run following code in controller to generate jwt token with correct secret and key
jwt.sign({ token: <generated token key> }, '<generated token secret>');


Step 6 – Add the newly generated jwt token to http request of requesting site/domain:

  • In your sites service making the request to backend api, add header with jwt token as follow:
'use strict';

<Module>
    .factory( '<Service>', function( $http ) {
        return {
            request: function() {
                return $http.get( <backend location>/<request parameter>,
                    {
                        headers: {
                            'x-access-token': '<generated jwt token>'
                        }
                    }
                );
            }
        }
    });

Leave a Reply