Authenticating Express React App - Part2

As we discussed in Part 1 on how to do the client side part of the token based authentication in Express React app, this post will focus on server side of the authentication. So lets get started -

Exploring the Idea

Server side has multiple responsibilities. Below are listed almost all of them -

  • Generate a HS256 encrypted token with minimal required User details and a Private Key.
  • Have a way to Call Login/Logout/Register routes.
  • Use in memory DB ( Redis in our case ) to persist the token, have a defined TTL
  • Call the DB to validate the token with every call that wants access to any private data.
  • Invalidate token/user if token is invalid/expired and allow the client side to immediately delete all the stores and logout the user.

Here are certain advantages of the above approach -

  • Anything in memory is much faster than reading disk. With this, you can reach to a minimum latency.
  • Keeping your authenticator separate from main server offers several security advantages.
  • Most important, You now have Separation of concerns. Client side is independent and hence is faster than ever, server need not care about session or user any more and the in memory DB fetches result very quickly.
  • There are leaps of other advantages, I recommend reading Stateless Tokens

Lets get to do some coding then -

Here is what my package file looks like

"dependencies": {
    "body-parser": "^1.17.1",
    "express": "^4.15.2",
    "flux": "^3.1.2",
    "jwt-decode": "^2.2.0",
    "jwt-redis-session": "^1.0.5",
    "morgan": "^1.8.1",
    "react": "^15.5.0",
    "react-dom": "^15.5.0",
    "react-router": "^3.0.2",
    "redis": "^2.7.1",
    "request": "^2.81.0"
  },

Next is our Routes file. This file handles the POST calls to Login and Logout. Its straight forward code, should be easy to understand.


/** Login Route
 * Create session in redis
 * @return token
 */
router.post('/user/login', (req, res) => {

  const options = {
    url: 'API Server URL',
    body: req.body,
  };

  request.post(options, (error, response, body) => {
    if (!error && response.statusCode >= 200 && response.statusCode <= 304) {

      // this will be attached to the JWT
      var claims = {
        user: body.user,
      };
      // create session & return the token
      req.jwtSession.create(claims, (error, token) => {
        res.json({
          access_token: token
        });
      });
    }

    // Error Occured
    else {
      res.status(500);
    }
  });
});

To give more context, I am using Redis to store the required user details and generate a token with the Redis Key which is passed to the client side for persistence. Now, every Api call can be verified by decrypting the token, getting the ID and making a query to redis to check if its valid or not. If it is invalid, send a response in such a way so that the client can immediately log out the user.

You can always grab the code from GITHUB. Share your comments or if you feel a better way, raise an issue in git or you want to collaborate, then raise a pull request.