Best Guide to JSON Web Token (JWT)
By: Ajinkya Bhuwad
Tags: Json Web Token, Authentication, Security, Security Token, Cybersecurity

“A JSON Web Token (JWT), pronounced ‘jot’, is an open standard (RFC 7519) which is used for securely transmitting information between entities as a JSON object.”

It is a compact and secure way of exchanging information over the network. JSON Web Token helps to maintain the integrity and authenticity of the information because it is digitally signed using secret or public/private key pair using RSA or ECDSA.

An important thing to keep in mind about JWT is that it is a signed token and not an encrypted one. Therefore, even though JWT can verify the integrity of the claims contained within it, it cannot hide that information. And because of that, it is advisable not to put any sensitive information within the token.

Why we need JSON Web Token?

HTTP is a stateless protocol that means a new request does not remember anything about the previous one. So for each request, you need to login and authenticate yourself (figure 1). Now, this sounds like a lot of work.

Figure 1

So, the solution to deal with this is the use of what’s called a session. A session is an object stored on the server that helps the user to stay logged in or to save any reference to their account. Figure 2 shows the overall flow of this process.

Figure 2

First, the user submits a username and a password that are authenticated by the server. If the authentication is successful a session ID is generated for the respective client. The generated session ID is returned to the client and is stored on the server-side as well.

Now, the client just needs to send its session ID along with the request to authenticate itself and retrieve necessary information. The server will then check if the session ID is valid or not. If the session is still valid, it will respond with the requested webpage/data. And if not, the server will respond with an error message stating that the request made is unauthorized.

Problems with Session-based Authentication

Scalability : The sessions need to be stored on the server, either in memory or in a database. In the current API era, a server can receive a large number of requests, and hence the server needs to be scaled up. Adding new resources can increase the complexity of the infrastructure as well.

Session Management: The server needs to manage the sessions by keeping track of all the active, inactive (expired, invalidated) sessions. The expired or invalidated sessions need to be removed from the memory.

Performance: For every request, the server needs to perform a lookup into the memory to check if the provided session object is valid or not. This back and forth can mark down the server.

The better and effective solution

The JSON Web Token (JWT) does not use sessions and hence prevents the above problems. When you send your credentials to the server instead of making a session, the server will return a JSON Web Token. You can use that JWT to do whatever you want with the server (Of course, the things that you are authorized to do).

Consider a JWT like a hotel key: When you enter the hotel, first you need to register yourself at the reception to receive your key card. You can use that key card to open and close your room, access common amenities like Bar, Fitness Centre, etc. But you cannot use that key card to access someone else’s room or Manager’s office since you are not authorized to do so. The key card comes with an expiration date, and it becomes useless once your stay has ended at the hotel.

Similarly, you can use your JWT token generated from one server to access resources on different servers. The JWT token contains claims like expiration date/time that can be used to check its validity..

Structure of JSON Web Token

A JSON Web Token is nothing but a long encoded text string which is made up of three parts separated by a period. These parts are:

Header Payload Signature

A typical JWT looks like the following:

header.payload.signature

Let’s see detailed break down of all the three parts.

Header

The header consists of two parts i.e. the type of token and the algorithm used for signing (such as HMAC SHA256 or RSA). The token type helps to interpret the token and in this case it’s JWT. For example,

{

"typ": "JWT",

"alg": "HS256"

}

This header is then encoded into base64 to form the first part of the JWT.

Payload

The payload consists of the session data called as claims. Claims provide information about the client/user. There are three types of claims: registered, public, and private claims.

Registered Claims: These type of claims are predefined claims which can be used for increasing the security. These claims are not mandatory but recommended. Some of these claims are:

iss (Issuer) Claim: The “iss” claim helps to identify the issuer of the token.

The “iss” claim helps to identify the issuer of the token. sub (Subject) Claim: The “sub” claim identifies the subject of the JWT.

The “sub” claim identifies the subject of the JWT. aud (Audience) Claim: The “aud” claim identifies the recipients that the JWT is intended for.

The “aud” claim identifies the recipients that the JWT is intended for. exp (Expiration Time) Claim: The “exp” claim is used to identify the expiration time on or after which the JWT must not be valid. Its value must be a number containing a NumericDate value. One important thing is that the current date/time must be before the expiration date/time.

The “exp” claim is used to identify the expiration time on or after which the JWT must not be valid. Its value must be a number containing a NumericDate value. One important thing is that the current date/time must be before the expiration date/time. nbf (Not Before) Claim: The “nbf” claim identifies the time before which the JWT must not be accepted for processing. The current date/time must be after or equal to the not-before date/time

The “nbf” claim identifies the time before which the JWT must not be accepted for processing. The current date/time must be after or equal to the not-before date/time iat (Issued At) Claim: The “iat” claim is used to identify the the time at which the JWT was issued. This claim can be used to determine the age of the JWT.

The “iat” claim is used to identify the the time at which the JWT was issued. This claim can be used to determine the age of the JWT. jti (JWT ID) Claim: The “jti” claim gives a unique identifier for the JWT. The “jti” value is a case-sensitive string and it should be assigned in such a manner that ensures that there is a negligible probability that the same value will be repeated. The “jti” claim can be used to prevent the JWT from being replayed.

Public Claims: These type of claims can be defined by group of people using the JWTs. Whenever any new claim name is defined it is necessary that it should be registered in the IANA “JSON Web Token Registry” or it should contain a collision resistant name to avoid collisions.

Private Claims: These are custom claims defined and created by two parties in order to exchange information between them.

An example of payload is as follows:

{

"sub": "user123",

"name": "John",

"role": "developer",

"exp": "1606595460",

}

The payload is then Base64Url encoded to get the second part of the JWT.

Signature

Signature is the most important part of JWT which helps to verify if the information within the token has been tampered with or not. It can be also used to verify that the sender of the JWT is who it says it is.

In order to calculate the signature, you require three things: an encoded header, an encoded payload, and a secret. First, you will take the encoded header and encoded payload and concatenate them with a period separator to form a string. This concatenated string will be hashed using an algorithm specified in the header and a secret key to calculate the signature.

Consider the following example where we will be using the RSA algorithm to generate a signature.

RSA(

base64UrlEncode(header) + "." + base64UrlEncode(payload), secret

)

Now let’s put all three parts together to get a JSON Web Token.

We have three Base64-URL strings, which can be concatenated with a period between each. The JWT is very compact and can be easily exchanged in HTML and HTTP environments.

The header and payload can be easily decoded (since it’s just base64) to retrieve information contained within the token. The signature can be just used to maintain the integrity of the token and not to secure the contained information. Therefore, you should pass any sensitive information in the token and if you want to pass make sure you encrypt the token to secure it.

How does a JSON Web Token work?

When a user sends his credentials to the server to login, the server authenticates the user. If the authorization is successful, the server sends a JSON Web Token to the user. The user can use the JWT to request any protected services/resources from the server by including the JWT in the Authorization header using the Bearer schema.

Authorization: Bearer <token>

When the server gets a request from the user to access any protected content, the protected routes of the server will look for a valid JWT in the Authorization header. If the token is present and is valid the server will allow access to the user.

The JWT contains necessary information about the user that can be used to identify the user, know the user’s privilege, and serve the user accordingly. Because of JWT, the server does not need to query the database every time a request comes in to check if the user has the necessary rights or not.

Figure 3

Every token assigned by the server is signed by a secret key known to the server only. Therefore, only the server can use the secret key to verify the token and to check if the token has tampered. If an attacker tries to make any changes in the token (like granting admin privileges), the signature of the token needs to be calculated again that will require the secret key. Since the attacker does not have a secret key making any changes to the token will invalid it. The server will discard such requests to prevent unauthorized access.

Advantages of JSON Web Token

Compactness: JSON is less verbose than XML and therefore when it is encoded it takes up less space making JWT more compact then SAML.

JSON is less verbose than XML and therefore when it is encoded it takes up less space making JWT more compact then SAML. No need of Session: The JWT can contain all the necessary information about the user and therefore there is no need to maintain a session object on the server, saving up server memory.

The JWT can contain all the necessary information about the user and therefore there is no need to maintain a session object on the server, saving up server memory. Built-in Expiration: The JWT has claims that can be used to assign it a expiration date/time. Therefore, the token can become invalid on its own after the expiration period.

The JWT has claims that can be used to assign it a expiration date/time. Therefore, the token can become invalid on its own after the expiration period. No need of Cookies: The token can be stored in the localStorage, indexDB, or some native store. This will provide a protection against CORS and CSRF attacks.

The token can be stored in the localStorage, indexDB, or some native store. This will provide a protection against CORS and CSRF attacks. Compatibility: In most programming languages, JSON parsers are popular because they map directly to objects. Contrary, there is no natural document-to-object mapping in XML. This makes it simpler than SAML assertions to operate with JWT.

That’s it! Now you know pretty much everything about JSON Web Token.