An(other) Introduction to JWTs

You probably know what JWTs are. In all probability, you would already be using them. This post tries to (re)introduce the concept and its usefulness in the Microservices world to beginners. But if you have no idea about JWTs, read on!

Ever wondered how the login information of all your various applications, mobile or web, are handled? Or how does the “Login using Google/Facebook/Github etc” work? JWTs are probably in use, behind the scenes to enable these and more.

JWT stands for JSON Web Token. It is an open internet standard that allows you to securely transmit information between two parties - client & server or server to server - as a JSON object. These tokens can be independently verified by any party that receives it - a very useful property while creating microservices.

What’s in a token?

All JWTs have a defined structure: header.payload.signature All the three components are base64 encoded separately.

The Header

The header should at least contain:

  • The Token Type: This will always be JWT, in this case
  • The Signing Algorithm (More on this, in the signature section)

In JSON form:

{
    "alg": "HS256",
    "typ": "JWT"
}

This JSON is base64 url encoded to form the header.

The payload

This part of the token will have the data that is being shared between the parties. This data is usually referred to as claims. There are three kinds of claims:

  • Registered Claims
    • These are a list of recommended, but not mandatory, keys that should belong to the payload. These keys will give certain useful information to the parties that use the token. One very common key is exp - The token expiry time. Some other common keys are sub and aud
  • Public Claims
    • These are a list of publicly recognized keys that can be used. These keys can be defined by anyone. The only condition is that the key must be registered in the central IANA registry. One very common key is scope
  • Private Claims
    • These are again custom keys but they are not registered anywhere. The sender and receiver are the only actors that need to acknowledge this key.

Once the payload is created, it is also Base64 Url encoded.

The Signature

This is the important part of the token. This part is used to verify the authenticity of the token as well. Remember the alg defined in the header? That is the Signing algorithm that will be used to generate the signature. There are many signing algorithms out there. But the logic is the same:

SIGN_ALGO (Encoded_header, encoded_payload, secret_key(s))

The secret_key portion will differ according to the algorithm. For example HS256 will use a randomly generated hash code as the secret key, while RS256 will use a public key, private key combination. The algorithm that needs to chosen, depends on the application - just server side validation or server and client side validations. More secure implementation will also encode the generated signatures.

Where are they used?

As is obvious by now, the primary use of these tokens is for Authentication purposes. A common web use case is login and further authentications. It will be something like this:

  • The client tries to login to the server using a username and password
  • Once the server verifies the password, it generates a unique token for the client and sends it back
  • All future requests from the client will contain this token, thus letting the server know that it is authorized

Compared to a session management approach, this offers better client-server separation. The server doesn’t need to keep track of the number of clients anymore. It will respond to any request with a valid token. This is the main reason for the popularity of JWTs in the microservice world. Now obviously, there are many ways in which this simple concept can be applied. This will soon lead to the requirement of a standard.

OAuth 2.0

OAuth 2.0 is not a JWT protocol. They are two different things that can be used together. OAuth (Open Authorization) is another open standard that defines how access delegations can be handled. The second version aims to simplify client - server interactions in mobile, web and desktop applications. It defines various “flows” that these applications can follow to handle Authentication / Authorization. One such flow is the password flow described in the previous section.

The central idea behind all the flows is to use some sort of a bearer token to authenticate a request. A bearer token can be passed in the header of the HTTP request under the Authorization key. Any server that implements one of these standard flows, will then look for this token, verify it and then serve the request. The OAuth website has a list of references and definitions for the various flows and app types.

JWT fits in nicely as a possible bearer token and it is also easy to use. Thus most OAuth implementations use JWT as the token and this can lead to the assumption that JWT is the OAuth 2 standard.

How does “Login with X” work? This is another OAuth 2 flow. We will look at it in the next post. In the meantime, if you would like to play around with JWTs and see how the various algorithms and combinations work, head over to jwt.io


Subscribe to the Blog!

Want to get notified about the latest updates?

Subscribe Via RSS  rss Subscribe Via Email