PC#21 - JSON Web Tokens and Authentication

A Big Interview Mistake and More...

Hello, this is Saurabh…👋

Welcome to the 141 new subscribers who have joined us since last week.

If you aren’t subscribed yet, join 2000+ curious Software Engineers looking to expand their system design knowledge by subscribing to this newsletter.

In this edition, I cover the following topics:

🖥 System Design Concept → JSON Web Tokens

🍔 Food For Thought → A Big Interview Mistake

So, let’s dive in.

🖥

System Design Concept

JSON Web Tokens and Authentication

JSON Web Tokens or JWTs (pronounced as JOTs) is a standard for defining tokens.

You can use them to represent claims between two parties in a secure manner.

A single JWT can contain all the required information about an entity, making it an ideal candidate for authentication.

Here’s what a typical JSON Web Token may look like:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Looks like gibberish?

In reality, it’s a compact, printable representation of a series of claims, along with a signature to verify its authenticity.

This makes them an ideal candidate for authentication.

Unlike session-based authentication, the server receiving a JWT doesn’t need to check a session storage to validate the token. The JWT has all the necessary details.

We did talk about session-based authentication in an earlier post:

The Components of a JWT

There are three main components of a JSON Web Token.

Here’s an illustration:

Let’s look at each component one by one:

Header

Every JWT carries a header with claims about itself. These claims specify the algorithms used for signing and/or encrypting the JWT.

The only mandatory claim for an unencrypted JWT header is the alg claim.

It specifies the main algorithm such as HMAC SHA256 or RSA used for signing and decrypting this particular JWT.

However, for unencrypted JWT, alg is as follows:

{
   "alg": none
}

Other header claims are optional and include the typ and cty claims:

  • typ specifies the type of the token i.e. “JWT”

  • cty is the content type and is needed for cases where the payload of a JWT is another JWT.

Payload

The second part of the token is the payload, which contains the claims and the user data.

There are three types of claims:

  • Registered claims or predefined set of claims that are not mandatory but recommended. For example, issuer (iss), expiration time (exp), subject (sub), and so on.

  • Public claims are claims registered with the IANA JWT Claims registry.

  • Private claims that can be defined by the users (consumers and producers) of the JWTs

Signature

The signature part of the JWT is created by taking the encoded header, encoded payload, a secret key, and the algorithm specified in the header and signing it.

The goal of the signature is to verify that the message wasn’t changed along the way. The receiver can use the signature to verify whether the sender of the JWT is who it says it is.

JWTs versus Session-Based Authentication

This is an eternal debate full of confusion.

But if you cut through the clutter, the debate ultimately boils down to just one thing - stateless vs stateful authentication.

With session-based authentication, you store the session information in a database or a session store.

Here’s how the whole process works:

  • The user makes a login request

  • The frontend sends the request to the backend server

  • The backend creates a session using a secret key and stores the session information in some sort of storage (database or cache)

  • Next, the server sends a cookie back to the client (the browser)

  • However, the cookie contains the unique identifier for the session

  • The user makes a new request to view another page

  • The browser sends the session ID as part of the cookie and the server can verify the session and the user details using this ID

Check the below sequence diagram for reference:

Here’s a more simplified look at the same process:

But what about JWT-based authentication?

The process is quite similar except for one major difference.

You don’t store a session in the session store.

Here’s how the JWT-based flow works:

  • The user makes a login request

  • The authentication server verifies the credentials and issues a JWT. This JWT is signed using a private key. No database call is made

  • The JWT is passed to the browser using a cookie.

  • For every subsequent request to the server, the browser sends the cookie containing the JWT.

  • The server can use the secret private key to validate the JWT and get the user information. No database call is needed.

Check the below sequence diagram for reference:

Also, here’s a more simplified look at the same process:

Pros of JWT

JWTs offer some cool benefits such as:

  • You don’t need a separate storage for the session data. The entire information is right there in the JWT

  • It’s also easier to scale the client and the server.

Cons of JWT

JWTs also have some important disadvantages as well that you must consider before adopting them:

1 - Invalidation

Once your server signs a JWT, it’s not easy to invalidate it.

If the signature is valid and the JWT’s expiry timestamp has not passed, it will be considered valid by the server.

This is a big problem.

If a user requests to log out of all devices, there is no easy way of doing this. You can theoretically revoke the secret key used to sign the JWT but that would invalidate all JWTs used by that key.

With session-based authentication, you can easily revoke a particular session ID by deleting it from the storage.

You could go for the solution to keep track of invalidated tokens but that introduces stateful behavior similar to sessions. In defense of this point, however, the list of invalidated tokens will be far smaller than the list of valid sessions in the session-based approach.

2 - JWTs take up more space

JWT tokens are not exactly small. 

When using stateless JWT tokens, where all the data is encoded directly into the token, you will quickly exceed the size limit of a cookie or URL.

Sure, you might try to store it in Local Storage, but that opens you up to security risks.

3 - Stale Data

Similar to a cache, the data in a stateless token can “go stale”, and no longer reflect the latest version of the data in your database.

This can be a serious security concern.

For example, it can mean that somebody has a token with the role of “admin” even though you may have revoked their “admin role”. Since there’s no easy way to invalidate a token, you may find it hard to remove their administrator access reliably.

Best Practices for using JWTs

Despite their possible shortcomings, JWTs are still quite popular and I’m not discouraging you from using JWTs.

However, here are some best practices that can help you out:

  • Always validate the signature of the JWT to ensure that it hasn't been tampered with. The signature provides integrity to the token and ensures that the claims have not been altered.

  • When signing JWTs use strong unique secrets for each environment (development, production, etc.). Make sure that the private key is secure.

  • Set a reasonable expiration time for your JWTs. The chance for an attacker to misuse a stolen token is less likely.

  • Implement token refresh, so that the user doesn't need to re-enter their credentials. This way you don’t have the risk of long-lived tokens.

  • If storing tokens on the client side, ensure they are stored securely. For web applications, using HttpOnly and Secure flags for cookies can enhance security.

  • Implement mechanisms for token revocation in case a token needs to be invalidated before its expiration date.

🍔

Food For Thought

👉 Avoid Bragging in an Interview

A real interview situation I witnessed.

  • The candidate told the panelist that he learned a new technology every month.

  • The panelist got interested and asked what was the last thing he learned.

  • The candidate answered - “Kubernetes”

  • The panelist started asking a few questions about Kubernetes

  • But the candidate couldn’t answer and revealed that by learning he meant he had just watched a few YouTube videos and had no practical experience.

Needless to say, the interview didn’t go too well. Trust was broken and the candidate was rejected.

There were some hard-hitting lessons from this situation that apply to everyone looking to ace their interviews.

I shared them on X(Twitter) and the response from the folks was overwhelming.

Do check out the post below as well as the responses👇

👉 Non-Stop Meetings for Senior Engineers

As you become a senior engineer, you’re expected to attend more meetings.

And the more time you spend in meetings, the less you can focus on your tasks.

Would you be okay to stay at the “engineer” level if it meant avoiding non-stop meetings?

The below post raises an important question👇

That’s it for today! ☀️

Enjoyed this issue of the newsletter?

Share with your friends and colleagues

Also, send them over here to subscribe.

In case you want me to cover any specific topic in future editions, please don’t hesitate to fill out the below idea-suggestion form.

See you later with another value-packed edition — Saurabh

Join the conversation

or to participate.