Json Web Token (JWT) : Stateless Authentication

The development of stateless applications help in high scalability and load distribution. The intent of the REST api is stateless application development, so that the request can be routed anywhere thereby handling the heavy load. Let's look at the role of auth tokens in making the highly stateless authenticated application.

Session Based Authentication :

When the user tries to login using his credentials, the backend server fetches the details from the database and validates the user. The backend server creates the sessionId when the user is authenticated and sends it as a response to the client. The client sends the sessionId for all the consecutive requests of the same user. This sessionId is checked in the backend and request is allowed further. Now let's look at the possibilities and issues depending on the storage of the sessionId in the backend.

Session Id stored in servers:

Session In Server.JPG

Consider the above architecture. The user is hitting the "/login" endpoint with the credentials. The backend server verifies the data by fetching it from the database for the corresponding user and creates a sessionId after verification. Now consider this sessionId created is stored in Server 1 for future authentication of the user and sessionId is returned back as response to the client.

Now, consider the user hits the "/getFeeds" endpoint with the sessionId passed in the request and the load balancer redirects it to Server 2. As the sessionId was cached in Server 1 and Server 2 doesn't have it cached for this user, the Server 2 will respond with the auth failed which might lead to logging out in the client side. You might already have observed the problems of scaling in this architecture as it might lead to same issues with the n number of servers added creating a bad user experience. Invalidating and clearing the sessionId in each server in sync also becomes a nightmare.

This also creates a stateful architecture which violates the intent of REST.

Session Id stored in database:

Session In db.JPG

Now, to solve the above problem we can save the sessionId corresponding to each user in the database as shown in above diagram. This would solve the above problem of scaling the architecture. But consider the amount of latency, load on database and cost it would produce for the large applications handling millions of requests, as each request needs to hit the database for fetching the sessionId.

Now handling the data in separate cache might solve the above mentioned problems but this also increases the overall cost and overhead of introducing the proper caching strategy to invalidate and update the cache according to latest data.

Because of these issues Json Web Tokens (JWT) came into picture. Let's have a look at how JWTs work

Json Web Token (JWT):

JWT.JPG

JWT is stateless authentication where nothing needs to be stored in server, hence the intent of REST api is also fulfilled perfectly. Above diagram shows the architecture with JWT. The user hits the "/login" endpoint with credentials and the load balancer redirects it toServer 1. The data is fetched from the db for the corresponding user and authenticated.

The JWT is created using a secret string that is stored in each server.

Now, the JWT has three parts :

  1. Header : The header has the metadata about the JWT and the payload.
  2. Payload : Contains all the useful info needed to authenticate the user in consecutive requests. We should avoid putting confidential data in payload as the header and payload are just encoded using encoding algorithms and it can be decoded by anyone.
  3. Signature : The signature is created using the header, the payload, and the secret that is saved on the server. And this whole process is then called signing the Json Web Token. The signing algorithm takes the header, the payload, and the secret to create a unique signature.

Next, the server then sends that JWT back to the client which will store it either in a cookie or in local storage. The client sends all the consecutive request with this JWT token to the backend server. Consider the same user hits the "/getFeeds" endpoint and the load balancer redirects it to Server 2 this time. Now the server needs to verify if the user is actually the one he claims to be. The server will decode the header and payload from the JWT obtained and try to create a signature with the help of the secret string stored in the server. Now the JWT also contains one signature and if nothing in the payload has changed and if the user is same, the new signature created in the server and the signature in the JWT must match. If it matches it verifies that the user is same and is already authenticated. Hence the server allows the request to proceed further.

Consider the payload has been edited in the client side or somewhere in network layer. But there is no way the client or the hackers would know the secret string as it is securely stored in the server. Even the signature in the JWT could not be accessed as it is encrypted. Hence, even if the payload changes, the authentication in server would fail as the new signature created using the secret string would not match the one stored in JWT, as the payload was changed.

Now each server would have this secret string stored securely and any server can handle the request without any issue. This makes the system highly scalable and highly tolerant to load. The system also becomes completely stateless as nothing is stored in server and the intent of the REST api is completely fulfilled.

This completes the overview of JWT. Do like and comment which encourages me to write more such contents. Do follow me on LinkedIn for more technical blogs and posts.