JSON Web Token Concepts

There are many technical articles about JSON web tokens (JWT) on the interwebs, but I haven’t found one that explains the problem and key aspects of the solution to my satisfaction.

The problem: You’re building a web service that clients access — typically, using REST APIs. You want to make sure only the right parties have access to the right APIs. How do you do that?

The classic way of doing that is:

  • Authenticate user (say using username / password)
  • Create a session object and store it in the DB. Session object contains information that can be used to determine what operations the logged-in user can do. E.g. session object may store that this user is an admin and therefore can delete stuff. Session object also has an expiry time.
  • The session object is assigned a random id and this session id is returned to the client. This is supposed to be hard to guess.
  • The client presents the session id along with every API request. This may be done via cookies or via custom HTTP headers.
  • The service looks up the session object using the id presented and checks if this user can perform the operation. E.g. non-admin user trying to delete stuff. Returns error code if not allowed, otherwise pass the request through.
  • If the session object has expired, redirect user to authentication page

This solution is not a bad one, but has drawbacks. Every API request requires accessing the DB to fetch session object. This can put a lot of pressure on your DB. Expired sessions need to be cleaned up once in a while or your sessions table could grow.

One great advantage of this approach is that all the session state lives in the server — it is possible to force a user off the system by deleting their session object. This can come in handy if it seems like there’s some nasty stuff going on.

Can We Do Better?

If the contents of session state were to be stored on the client side, the server won’t need to keep a sessions table and clean up expired sessions. The problem is — malicious clients can tamper with this information. Example, a malicious user may simply set a is_admin flag to true and do bad things.

What if the session information were stored on the client side in a tamper-proof manner and presented with every request?

In the above flow, the key change would be that the service returns entire contents of session object to the client. The client presents the entire contents of the session object along with every request. The service can do exactly the same checks to determine if the client is authorized to perform the operation.

It all comes down to: how can we ensure that the session object has not been tampered with by the client? The service can generate a hash of the session object using a special function with a secret key known only to the service (see MAC for details). This is sent back to the client along with the session object and is part of every request as well. Upon receiving the session object, the service can verify integrity of the session object by recomputing the MAC using the same function and matching the codes.

Thus, the key aspects of JSON web tokens are:

  • Computing MAC for session object on server side and sending it to client
  • Client sending session object + MAC code with every request
  • Server verifying integrity of session object and doing auth checks
With JWT, the server doesn’t need to store session object in the DB. This keeps your DB nice and happy.

The actual “JSON” part in JWTs is part of the standard. You can find several articles that explain the structure in detail here, here and here.

Homework Assignment

For readers who’ve made it this far, here’s a little teaser. Let’s say we want to build a safety mechanism to force all users to re-authenticate themselves. With the DB solution, we can simply delete all session objects. How can we do that with JWTs?

Siva Narayanan

I am known to be "the CTO of one, the father of two, and the roasting baba of many."

More of our stories from

Engineering
Demystifying Class Variables In Python

Understanding class variables in python

Read more...
Interview Experience: Backend Engineering Internship at Fyle

Wanna know the secret to crack backend engineering interviews? Learn them here and intern at Fyle!

Read more...
The curse of being a Senior Engineer, how to deal with timelines, frustrations, etc

Being a good developer is 50% skill and 50% emotional support; here's my secret to balancing both at the right amount!

Read more...
How did I build cropping of receipts in the mobile app?

Follow Yash's journey of what it takes to reduce manual work for our customers when receipts come in all shapes and sizes!

Read more...
How did we increase Data Extraction accuracy by a whopping ~50%?

Wanna know the secret of data extraction, the complex machine learning models we use, the experiments we did? Read on...

Read more...
The not so secret sauce of my work

From chaos to clarity, follow Chethan's not so secret sauce to excelling at work!

Read more...
From Zero to Hero: The Policy Tests Journey!

The story of policy tests at Fyle

Read more...
How Fyle changed my life from a naive intern to a confident Engineering Lead

A blogpost that documents Shwetabh's journey at Fyle.

Read more...
Vikas Prasad @ Fyle

This document is a user guide to Vikas at work.

Read more...
Gokul K's README

This document is a user guide to Gokul at work.

Read more...

All Topics