DEV Community

Mehak Saini
Mehak Saini

Posted on • Edited on

Why JSON Web tokens are required?

JSON web tokens (acronym JWT, pronounced at JOT) were introduced in 2010 as a means of communication between two parties in the form of a JSON object. They can be encrypted and are popularly used over session id in authorisation mechanism in a server client architecture. Let's discuss what has made it so prevalent.

Server-Client Architecture

In this scenario, if a client requests a protected page(https://dev.to/new) from a server(by protected I mean the one shielded with some authentication mechanism), the server renders a login page . User( the term client and user are used interchangeably ) enters the user credentials and is successfully logged in. If in a subsequent request, the client requests the same url (https://dev.to/new), server has no way of knowing that it has already authenticated this user and re-renders the login page.

Solution1

Session id

So as a solution to the above problem, the concept of session id was introduced wherein the server creates a new session when a client requests anything for the first time. It then stores and passes the session id back to the client so that it can identify the client in case of any subsequent requests. Though it is a feasible solution and widely used, it has its own drawbacks.

Drawbacks

As the number of requests increase, there is a need for increased scalability.

Vertical scalability

Increase the number of resources for a server. It is an expensive solution

Horizontal scalability

Increase the number of servers.

Though the latter is feasible, the downside is that as you increase the number of servers, you need to put a load balancer in front of it which is responsible for request management. Now, the requests can go to any server irrespective of the client requesting it. So, if a user1 is authenticated with server1 and requests the same page again, and now the request goes to server2, some mechanism is need to tell server2 that user1 is already authentication. Hence, there is a need of storing the session ids in a database or in an alternate solution, keep the servers in sync at all times which comes with its own overhead.

Solution 2

JWT

For servers implementing JWT, there is no need of session storage. When a client requests a protected resource, server creates a JWT token and passes it to the client. JWT can contain user data along with other information in an encrypted format. Server does not store the JWT token, rather it stores the encryption key, so the next time user requests the same resource, server uses the key to decrypt and identify the client.

Top comments (5)

Collapse
 
jcj profile image
John Christopher Jones • Edited

It's critical to recognize JWTs are not encrypted. They are signed, which is what gives us the confidence to trust them, but the contents of JWTs are publicly readable by anyone. JWTs are like an ID card laminated with a hologram. Anyone can read the ID and anyone can print a fake, but we trust that only the issuer could include the hologram so we trust that the information on the card is correct, would be destroyed by modification, and do not need to call the issuer to obtain any information that is printed on the card.

Similarly, you should assume JWTs will become public at some point and never include sensitive information in JWTs. JWTs have a built-in expiration mechanism, which you should always use, so that the authorization granted by the JWT is not permanent.

The "overhead" touched on in the article is twofold:

  1. If you have to talk to your authentication server with every single request, every server has to do a lot more work—your authentication server in particular.
  2. More importantly, the complexity of needing to bake that authorization conversation into every single server, service, and request, means your system is more complicated to build and more sensitive to failures like your authentication server failing.

By using JWTs, you can make authentication a single tiny service that doesn't have to know anything about the rest of your system. Similarly, all of your other systems that need authentication do not need to know anything about your authentication service. All they need to know is that the JWT is valid; they do not care how the JWT was created or acquired.

That means less traffic with your authentication server, but, more importantly, it means far less code has to be written that is coupled to your specific authentication implementation.

Collapse
 
ramriot profile image
Gary Marriott

IMO, while true for many use cases this is not true in the published rfc:-

tools.ietf.org/html/rfc7516 - Defines Encrypted Tokens
tools.ietf.org/html/rfc7515 - Defines Signed Tokens

There are use cases for both & use cases to Sign then Encrypt tokens. In cases where a client system generates an authentication token via API keys then a Signed token to the server system is appropriate. In the case of a Server passing a post authentication "session" token to a client where the client has no need to read the content it may be advisable to encrypt & sign, such that inadvertent leaks do not identify specific user accounts.

Agreed it is not advisable to put private info into a token, even if encrypted because perfect forward secrecy is unlikely to be maintained.

Collapse
 
jcj profile image
John Christopher Jones

Oh, interesting. Though I did realize that you could encrypt the values in the payload, I somehow completely missed that encrypted JWTs were a thing that exists. That's for the knowledge bomb!

So, my mistake: JWTs can be encrypted, but you should probably still act like they aren't.

Potentially, there are good reasons not to encrypt JWTs. If your auth server only returns a JWT, then you might rely on information within the payload (such as a user ID) to make additional API requests. This is especially likely with REST APIs you might not control. For example, one API might require a user ID in a URL, but the signed JWT is the only way your code can obtain that user ID.

However, using JWT payload contents leaks implementation details into other parts of your system. If you have a choice in the design, it's a better practice to treat your JWTs as opaque, whether they're signed JWTs or encrypted JWTs. That is, your code shouldn't need to care if JWTs switch from signed to encrypted one day.

Collapse
 
mehaksaini11 profile image
Mehak Saini

Thank you for your knowledge sharing 🙏🏻

Collapse
 
flaksp profile image
Petr Flaks • Edited

I found nice use case for JWT in my recent project. It's very useful in file uploading and other similar cases.

  1. Client asks for URL to upload image to via special API endpoint. Client should pass file purpose there (e.g. profile_avatar). In response server will return upload URL and some constraints for given type (max size, allowed MIME types, dimensions requirements, etc).
  2. Client uploads image there. If upload were successful, server returns JWT in response. If image does not fit in constraints, upload will fail with error.
  3. Client passes this JWT to avatar changing API endpoint.

Inside JWT there are URL to image, dimensions, size, MIME type, etc. Since JWT is signed and both file uploading server and API server share same keys, API server can validate JWT to be sure string was not modified, so it can be trusted and data inside it may be safely saved in database.