Authentication is one of the most important decisions when we are bulding a web application. Modern web apps are One-page apps, built on top of technologies like AngularJS . In that case, we don’t want to waste time building markup and representation layers, instead of that we are building APIs that our front-end consume. So these changes have led to new ways of implementing authentication into this modern applications.
There are basically two different ways of implementing server side authentication for apps that consist of a frontend and an API. The most adopted one is the traditional Session Based Authentication. In traditional authentication, the user logs in with its credentials, then the server validates the information and stores it in session objects, either in memory or on disk.
Common Session based Authentication problems
This Session based Authentication has the following problems:
When a user is authenticated, the server needs to remind somehow, usually keeping the information in memory. When many people are online, server overhead increases.
From the moment we keep user information stored on session, there are scalability issues. Imagine that our application needs autoscale to meet peak demands and load balancing across multiple servers. While we are keeping the user on the server session if there’s a new request sent to another node then user needs to log in again. This can be solved using the technique known as Sticky Session but even with that solution it doesn’t feel optimal. With token-based authentication, this is solved naturally, as we’ll review.
Most often we want our data to be consumed from multiple mobile devices (tablets, smartphones, etc …). In this scenario it’s important to worry about what is called CORS: cross-origin resource sharing or sharing of resources from different sources. When we use AJAX to retrieve data from our application, we can find us getting unauthorized requests because modern browsers don’t allow this type of behaviour for security concerns.
JSON Web Tokens
One of the best known solutions to authentication problems for APIs are JSON Web Tokens or JWT. The token-based authentication is stateless. This means that you do not save any user information on the server or the session. This kind of authentication sends a token for each request through the HTTP headers instead of keeping authentication information sessions or cookies. Thus, no state is saved between different requests of our application and our data can be consumed from different types of clients.
As tokens are stored on the client side, we don have to care about status information or session so our app application becomes completely scalable. We can use the same API for different apps likeWeb, Mobile, Android, iOS so we just worry about sending the data in JSON format and generate and decrypt authentication tokens through a middleware.
From user’s perspective, there’s no different between login in into an application that uses JWT and an application that uses traditional authentication. The user enters their credentials checked against the server’s storage or service, but rather to create a session and return a cookie, it will return a JSON object containing JWT. The JWT needs to be stored in client side, which is usually done in the local storage The JWT must be sent to the server to access protected routes. The token is generally sent via an HTTP Authorization Header.
You can think of this token as your hotel’s room card. When yo visit a hotel, you go to the hotel’s desk and you give your credentials so they give you a card. In this case, the card is your token and you’ll be able to access to your room with it. We can go into our room but we can’t use our card to go into other room. Who has the card? Does the hotel have it? No, we do have it, as we have the JWT and the server doesn’t store a session for us. When we leave, if we don’t return the card, we will have a useless piece of plastic. That means the tokens has an expiration.
In the next post, we will review the structure of a JSON web token and how can we implement it in AngularJS.