Token based authentication system in Node.JS

What is token based authentication ?-

At a very basic level, token based authentication works as follows –

  1. User enters username and password
  2. Token is generated on the server and sent to the client.
  3. With every subsequent request, the client sends the token to the server.
  4. Server validates the token and processes the request.

Why token based authentication ?

In traditional web applications we use sessions and cookies to store the user information, but when dealing with web applications that need to interact mobile or single page, this traditional model will not work. Some of the benefits of a token based authentication system are –

  1. Stateless way of declaring users and giving them access.
  2. Freedom to implement our own mechanisms.
  3. Simple yet very powerful.

Implementation

We have implemented a token based authentication in one of our Node.js / Express app.That application consists of :

  1. Public routes:- These are the routes that can be accessed by any one. There is no need of any validation.
  1. Member routes:- These are the routes that can be accessed only by people who are logged into the application. Each member also has different permission – read-only and read/write, admin.
  1. Super admin routes:-These are the routes that can be accessed only by the users who have super admin privileges. These are clients who have the ability modify the way our application behaves.

Implementation flow

The flow will differ based on the resource requested by the client.

  1. Client enters the username and password. If valid, then token is generated and stored in the database, along with information regarding the client for which it was generated. It is then sent as a response.
  2. The token is stored by the client. These tokens expire every two hours. After that the client has to re-authenticate to get another token.
  3. Every time a request is made by the client the token is sent in the request header.
  4. If the token is not valid we return 403 HTTP status to the client.
  5. If token is present and the route/resource is admin only we then validate to check if the token was registered for an admin user or not.
  6. If token is not associated with an admin client, we again return a 403 HTTP status to the client.
  7. If everything is validated successfully we then send the processed data as response to the user.

There are three different implementations based on the resource being accessed by the client –

Public routes

No validation, the request for resource is processed straight away.

token-based-authentication_o1

Member routes

  1. Client enters the username and password. If valid, then token is generated and stored in the database, along with information regarding the client for which it was generated. It is then sent as a response.
  2. The token is stored by the client. These tokens expire every two hours. After that the client has to re-authenticate to get another token.
  3. Every time a request is made by the client the token is sent in the request header.
  4. If the token is not valid we return 403 HTTP status to the client.
  5. If everything is validated successfully we then send the processed data as response to the user.

token-based-authentication_o2

token-based-authentication_o3

Super admin routes

The flow is similar to the one under Member routes but in addition one extra step is performed after the 4th step -Validate that the token is registered for an admin user, if not we again return a 403 HTTP status to the client.

token-based-authentication_o4

Technical implementation

At startup, our Node application checks the route based on configuration options provided and attaches callbacks. So for example, if we take the following routes –

        app.httpGet('users/', {
                isPublic : false,
                isAdmin : false
        }, callback);
        app.httpPost('login/', {
                isPublic : true
        }, callback);

httpGet and httpPost are wrapper methods on top of express’ post and get methods.

     app.httpGet = function(url, config, callback) {
                // Does some preliminary checking.
                bindRoute('get', url, config, callback);
        }
        function bindRoute(method, url, config, route) {
                if(config.isPublic) {
                        app[method](url, route);      // Method can be 'get', 'post', 'delete', 'put' etc
                } else {
                        // First validate the token
                        app[method](url, checkIfTokenIsValid);
                        // Admin only URL, validate if token is associated with a admin user.
                        if(config.isAdmin) {
                                app[method](url, checkIfAdmin);
                        }
                        app[method](url, route);
                }
        }

checkIfTokenIsValid method will check if the token sent by the client is valid and has not expired. If either of this conditions fail, it returns a 403 error.

Similarly, checkIfAdmin verifies if the token sent by the client has necessary admin privileges.

Drawbacks of this implementation

  1. This implementation checks only if the user is admin or member, but it is difficult to add any other role to the users. For example, if we also have another role to the user then that role cannot be added to these present implementation.
  2. Support for multi tenancy. Currently although the architecture has the ability to be used by multiple customers, there is a chance for data leakage.

Future enhancements

  1. Implementation of the roles for the members using this approach. Access will only be granted to the user based on the role user has.

Along with the token, we will store privileges that the user has and each time a request comes with that token, validation will be done to ensure that the user has necessary privileges to access that resource.

  1. Removing data leakage between the multiple customers using this application. This can also be carried out using a similar approach stated above.

Conclusion

Token based authentication is simple and very powerful mechanism to provide a stateless way of carrying out authentication. Everyone can have their own mechanism to generate tokens and implement their validation. We’ve explored one of the many possible ways to implement such a system. Comments and criticism are welcome.

Published by

Leave a Reply

Your email address will not be published. Required fields are marked *