JWT (JSON Web Token), why do we need it ? and how does it work ?
Authenticating and authorizing the external internet to internal systems constitutes crucial security stakes to every digital business in the world. With the evolution of modern systems, and the answers brought to many fundamental problematics such as partition tolerance, scalability, and many others, security is facing new challenges. traditional authentication solutions do no longer suit this evolution. That’s when JWT comes into play!
Before diving into JWT definitions and how it works, the first question to ask is why we need it ? and what answers does it bring us ?
Stateful Authentication : The old Fashion
HTTP protocol is stateless, which means every request made to a server, doesn’t know about the previous one, and every request should authenticate itself separately. The traditional way to deal with this stateless property of the HTTP protocol is using the server-side sessions (SSS). when a user is Authenticated (via username and password for example) the server creates a session which is tied to a unique session id. This id is sent back to the client so that the next time the client makes a call, he just have to embed his session id to be recognized.
Sessions face multiple problems, the first one is that sessions are not secure. As soon as a hacker finds a way to steal the session id (traditionally stored in a cookie) he can access to the server resources. The second problem is that sessions do not scale. let’s say you have two servers, S1 and S2 running behind a load balancer in order to distribute the incoming requests load between the two servers. If a client is authenticated by S1 a session is created and transferred to the client, the problem here is that the other S2 does not know about this session, thus, if the next request coming from the same client is redirected to S2. it will be unauthorized.
A stateless Authentication solution : JWT !
In order to embrace the stateless nature of the HTTP protocol, we need an authentication solution more efficient and more secure than sessions. that’s when JWT comes to play.
JWT or JSON Web Token is a compact and autonomous solution to securely authenticate clients, and authorize them to access the requested resource by exchanging a standardized token.
JWT is compact because of its small size represented in JSON format and transferred usually in an HTTP header (it can be transferred in a POST request parameter or a URL parameter as well), autonomous because it carries all the information needed about a client (no need for the server to look for the user information, in the Database for example) and secure because of the signature that allows the server to know if the token is authentic or has been forged.
Simply put JWT is a set of data in JSON format, signed by a server and used to authenticate and authorize a client.
JWT is formally defined by a Request For Comment (RFC 7519), which means there is an official document describing and defining its structure and how it works.
JWT Structure
Let’s have a look at the structure and the different parts of a JSON Web Token.
JWT is essentially a long encoded text, composed of three parts separated by a dot sign and each part is encoded as Base64URL. These parts are the Header, Payload and Signature.
The format of a JWT is therefore :
Let’s discover each part :
The Header :
Header describe the cryptographic algorithm applied to sign the JWT and optionally, additional properties of the JWT.
In the example above, we see that the type of the token is a JWT, and the algorithm used to sign the token is HMAC-SHA256.
Thus, the Base64 encoded header is :
The Payload
This is the most important part of the JWT, the Payload part contains the information (or claims in JWT Jargon) about the client. There are 3 types of claims, Registered Claims, which are defined by the IANA organism. They are the most used information in a token (Such as the issuer of the token, expiration time …). If the information we want to put in a token don’t exist in the Registered Claims list, then there is the Public Claims which is a list defined by those using JWT, however to avoid collision, this list is also maintained by the IANA organism. If none of the Registered Claims or the Public Claims contain the information we want to have in our token, then we might consider using Private Claims which are just information used in agreement between a producer and a consumer, and that doesn’t exist in the previous claims. Here is an example of a JWT payload :
In this example, the fields “sub”, “iss”, “aud”, “exp”, “nbf”, “iat”, “jti”, are Registered Claims. “name” field is a Public Claim. the field “roles” exists neither in the Registered Claims nor in the Public Claims, it’s a Private Claim. For the Registered claims here is what each field refers to :
sub : The subject, or who is this token intended to (a username in general)
iss : The Issuer of the token
aud : the audience of the token or who is it intended to
exp : The expiration time after which the JWT is not valid
nbf : Time before which the JWT must not be accepted for processing
iat : Identifies the time at which the JWT was issued.
jti : JWT ID, provides a unique ID for the token.
A useful thing to know about the claims is that they are all OPTIONAL.
The encoded payload is therefore :
The Signature
This is simply the part that allows the server to verify the integrity of the token. The signature is produced by executing the encryption algorithm (present on the header part) on the header and payload, combined with a secret key. Which looks like this :
In our case, (HS256) means that the algorithm used is the HMAC symmetric algorithm combined with SHA-256 hash algorithm, it could be an asymmetric algorithm such as RSA, combined with SHA-512, or it could be other combination of algorithms. you can read here to find out more about JWT signing algorithms.
When assembling the token, the Signature is also encoded. Finally after assembling our Header, Payload and Signature, the token looks like this :
Conlusion
To sum up, what JWTs really do is that they provide a means of maintaining session state on the client side instead of doing it on the server. And moving the session to the client means that you remove the dependency on a server-side session, but it imposes its own set of challenges, such as storing the token securely (especially against XSS and CSRF attacks) and transporting it securely.
In this article we covered the theory behind JWT, in a separate article we will see how to implement JWT with Spring Security and use it in a real life scenario.