What are JWT?

Translation available in: French (original).

What is it?

JSON Web Token (JWT) is a compact, URL-safe means of representing data to be transferred between two parties. The data is encoded as a JSON object that can be signed and/or encrypted.

This is, paraphrased, the definition from the IETF standard that defines it (RFC 7519).

What's the point? What's the use case?

So the goal is to transfer data, with some guarantees (or none, by the way): authenticity, integrity, even possibly confidentiality (if the message is encrypted). There are therefore many possible uses.

JWT is thus used in OpenID Connect to encode the ID Token that forwards to the application information on the authentication process that took place at the identity server. OpenID Connect also uses JWT to encode aggregated claims: information from other identity servers, for which we'll want to verify the authenticity and integrity.

A JWT might be used to authenticate to a server, such as with the OAuth 2 JWT Bearer (RFC 7523).

Still in OAuth 2 land, access tokens could themselves be JWTs (RFC 9068), authorization request parameters could be encoded as a JWT (RFC 9101), as well as token introspection responses (IETF draft: JWT Response for OAuth Token Introspection), and finally dynamic client registration uses a JWT to identify the software of which an instance attempts to register (so-called software statements of RFC 7591).

How does it work?

A JWT is composed of at least 2 parts, separated with a . (dot), the first one always being the header. Each part is always encoded as base64url, a variant of Base 64 with the + and / characters (that have special meaning in URLs) replaced with - and _ respectively, and without the trailing =.

There are two types of JWTs: JSON Web Signature (JWS, defined by RFC 7515), and JSON Web Encryption (JWE, defined by RFC 7516). The most common case is the JWS, composed of 2 or 3 parts: the header, the payload, and optionally the signature. JWEs are rarer (and more complex) so I won't talk about them here.

The header, common to both types, describes the type of JWT (JWS or JWE) as well as the different signature, MAC, or encryption algorithms being used (codified by RFC 7518), along with other useful information, as a JSON object.
In the case of JWS, we'll find the signature or MAC algorithm, possibly a key identifier (whenever multiple keys can be used, e.g. to allow for key rotation), or even a URL pointing to information about the keys (in JWKS format, defined by RFC 7517), etc.

In the case of JWS, the payload will generally be a JSON object with the transfered data (but technically could be another JWT).

The third part is the signature or MAC. This part is absent if the header says the JWT is unprotected ("alg":"none").

For debugging, one can use the JWT Debugger by Auth0 to decode JWTs (beware not to use it with sensitive data, only on JWTs coming from test servers).

⚠️ JWT being almost always used in security-related contexts, handle them with care, specifically when it comes to their cryptographical components.

One MUST use dedicated libraries to manipulate JWTs, and be careful to use them correctly to avoid introducing vulnerabilities.

RFC 8725 has a set of best practices when manipulating and using JWTs.

Criticism

Numerous security experts, among them cryptographers, vehemently criticize JWTs and advise against their use.

The main criticism relates to its complexity, even though it could look simple to developers:

As a result, a number of vulnerabilities have been identified; among them (identified as soon as March 2015):

Aside: despite ID Tokens in OpenID Connect being JWTs, you won't actually need to verify their signature as you generally get them through HTTPS, that already guarantees authenticity and integrity (and confidentiality), which saves us from a whole class of vulnerabilities.

Another criticism is due to the misuse of JWT, most often by ignorance or lack of expertise in software security: validity of a JWT is directly verifiable, without the need for a database of valid tokens or a validation service (authenticity and integrity are verifiable, so the validity period contained within in the JWT are reliable), but it makes the JWT impossible to revoke (unless you add such a mecanism –possibly based on the jti claim, initially designed to protect against replay attacks– going against the whole reason for which JWT was chosen in the first place). If a JWT is used as a session token for example, it then becomes impossible to sign out or terminate a session. In most use cases (in the specifications), a JWT is validated and used as soon as it's received from the issuer, so revocation is not even an issue. It's when a JWT is stored by the receiver for a later use that the problem arises (such as with a session token or an access token).

Some articles critical of JWT:

Discuss: Dev.to