JSON Web Token (JWT) explained!

Let's say you are Tony Stark (I miss him so much) and you want to log in to your systems to fight with the aliens. So how does his system makes sure that he is logged in so that he can save the world(New York) easily?

So, instead of him sending his credentials every time his applications/websites generate tokens that contain some information about him which makes sure that he is Iron Man and not some steel guy and keeps him logged in.

Hmmmm, What is JWT?

It is a way to securely transmit information between two parties over the internet.

So, whenever you login into a website it creates a JWT for you which contains information about you like your ids and roles. Then this JWT is sent to the server and the server includes this JWT in every request you make to the website.
The website then uses JWT to validate you and checks whether the token has not been tampered with and is valid.

What does JWT look like?

These tokens have three parts header, payload and a signature combined with a dot (.) between each of them.

JWT=[Header].[Payload].[Signature]

A header contains the algorithm and the type of token which is used to sign in the token.

Payload has the data which is being transmitted through JWT. It is a JSON object and can contain anything we want to transmit. Generally, it has a user ID and roles etc.

The signature is used to verify that the JWT is authentic and has not been tampered with. It is a combination of payload and header.

Here is a javascript code to make you understand it better:

const jwt = require('jsonwebtoken');

// Set the payload data
const payload = {
  userId: 3000,
  username: 'Tony Stark',
  role: 'admin'
};

// Set the options for the token 
const options = {
  expiresIn: '1d', // the token will expire in 1 day
  issuer: 'Jarvis.com' // the token issuer
};

// Create the token with the payload and options
const secretKey = 'Peter'; // the secret key used to sign the token
const token = jwt.sign(payload, secretKey, options);

// Print the token
console.log(token);

Here we have the payload which includes a user ID, username and role. We have also set the expiration date which will be 1 Day and the issuer which will go with the payload. We create the token using 'jwt.sign()' function and then print it in the console.

It can give the token which looks like a combination of strings :

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.*eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ*.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Here the bold part is a header, the highlighted part is the payload and the normal text or the last part is the signature.

Why do we set an expiration time?

The main reason for setting an expiration time is to limit the opportunity for an attacker who may have obtained a JWT. If the token expires after a short period, an attacker would have a limited time to use the token before it becomes invalid. This helps to reduce the impact of a stolen token and keeps us safe from attacks.

How do we store a JWT?

JWTs are generally stored in two ways :

  1. Local Storage: We can store them in a browser's local storage but this is more vulnerable to attacks so we need to encrypt it before storing it here.

  2. Cookies: It can also be stored in http-only cookies because it is not accessible from the javascript running in the browser and provides better security. We can set expiration time as well to provide an additional layer of security.

In JWTs two types of tokens are commonly used for authentication :

Access Token: It is a short-time token that is generated when a user is authenticated securely. It contains all the data required for used authorization like id, roles etc. Their life span is generally less than 1 hour and it is periodically refreshed so that the user remains logged in with the help of a refresh token.

Refresh Token: It is a token with a longer life span and it is issued with the access token. It is used to obtain a new access token whenever the current one expires and its duration can be days, weeks or months. When the access token expires, the client can use the refresh token to obtain a new access token without having to re-authenticate the user.

The use of both of them helps in improving the security of the authentication system because by using an access token the time for an attacker to misuse the stolen token is limited and even if he steals the refresh token he still needs to get the access token correct.

There are much more things to learn about JWTs, the authentication systems, how to implement them, JWT rotation etc. There are plenty of resources on the internet where you can learn about it, just like I am doing right now and I am excited to share my learning path as well.

Thank you so much for making it to the end of this blog. LOVE YOU ALL 3000.