What is a JWT token ?
JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.
Read the RFC for more information: Link
A real life example consist of a base64 string separated by 2 points:
When decoded gives us 3 parts, like in this picture:
In this case lets say the id of our User is « id », is our identification for the user. the « jti » will tell us about the source of the JWT token and identifies the session (in the general sense) that are active.
How are JWT issued ?
Before going further we need to make sure that we agree how JWT are issued.
For the first time, a user request login, and gets a token with an expiration date and for the sepiçcific device / client he js on. the token gets saved in the database along with the expiration date and the device/client.
When the users logout, the device/client forgets the JWT.
If the user connects again we check if the current JWT still valid, if TRUE, send the generated JWT for the same device/client.
Having this in mind, at any given moment we have the list of JWT tokens distributed, now I imagine the user gets his phone stolen and he want to revoke access to his account on the phone, naturally he will go to the web application and revoke the current session on his phone, BTW Facebook does exactly this.
How can you revoke the JWT ?
We don’t have to always revoke JWT, if a JWT is expired there is no need to blacklist it, the user will be asked to login again. On the other hand if the JWT still valid and revoked you need to keep track of it in a blacklist UNTIL it is expired.
To do this we will use Redis.
Why redis ?
- Fast in memory database, it is like asynchronous code when you are accessing efficiently the data.
- Supports TTL, Time To Live, after the expiration date the data will be deleted, it is only possible to do this on keys and values, you cannot do this on individual items of a list for example.
- Can be persisted to disk.
So to elaborate we will make « buckets » for JWT keys it can be for one day, or hour or even minutes depending on your needs and application traffic.
Depends on your need, if your application is high traffic, you may want to make different TTL shorter for each of « buckets » and JWT so the user and the clients will hit less your login endpoints.
First of all the JWT have an « exp » and « iat ».
exp is the expiration date.
iat is the Issued at.
Lets say we have 3 JWT, each one of them generated in different days, and the 3 of them got revoked and they still valid.
We make 3 Sets in Redis, each set will contain JWTs that will expire on the same day and are revoked. We regroup the JWT by day of their expiration. then set the TTL on each bucket with the duration until the JWT in that bucket expire.
At this point for each connection you know where this session is logged in from, and you can check if the JWT is blacklisted or not, of course if it is expired it will be automatically removed from Redis and when you try to recode it, you will see that is expired.
Hope this is clear.