JSON Web Tokens are a useful tool and a better way of implementing authorization in web applications, but what exactly are they and how do they work?
What is a JWT? A JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
A JWT is a means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS) and/or encrypted using JSON Web Encryption (JWE).
This information can be verified and trusted because it is digitally signed. JSON Web Tokens can be signed using a secret key (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
Authorization is commonly done by using a session. The critical difference between JWTs and sessions is JWTs are self-contained, while sessions are not.
A JSON Web Token contains:
So when the server receives a JWT, it can already retrieve all the information directly from the token, hence, self-contained. In contrast, a SessionID is merely a long, unique, random string. On its own, it has no information. When you make a request to a server with your SessionID, it needs to do extra work to find out which user it belongs to.
JSON Web Tokens consist of three parts separated by dots (.
):
{
“typ”: “JWT”,
“alg”: “SHA256”
}
a. Reserved: Claims defined by the JWT specification to ensure interoperability with third-party, or external, applications. OIDC standard claims are reserved claims. Below are some of the standard claims that we can use:
b. Custom: Claims that you define yourself. Name these claims carefully to avoid collision with reserved claims or other custom claims. It can be challenging to deal with two claims of the same name that contain differing information.
{
“sub”: “JohnDoe19”,
”iat”: “17837373”
}
// signature algorithm
data = base64urlEncoder(header) + “.” + base 64urlEncoder(payload)
Signature = HMAC-SHA256(data, secret_salt)
So when the header or payload changes, the signature has to be calculated again. Only the Identity Provider (IdP) has the private key to calculate the signature, which prevents tampering with the token.
Let’s take a look at the flow of JTW, to get a better understanding:
User signs in using “Username” and “Password.”
The server verifies the authenticity of your credentials (Username & Password).
If the credentials are authentic, the server creates a JSON object.
Next, the server serializes the JSON object, generating a token, and then sends it to the browser.
The browser receives the token and saves it in the cookies.
When next the user sends a request to a protected endpoint, the JWT is passed along in the request HTTP header.
The server checks the signature on the JWT to make sure the same server created the JWT. In this way, the JWT acts as a way to authorize users securely, without actually storing any information (besides the key) on the application server.
The server reads the claims and permits the request, after which it responds with the necessary data.
Here are some scenarios where JSON Web Tokens are useful:
Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services and resources that are permitted with that token.
Information Exchange: JSON Web Tokens are a good way of securely transmitting information between parties. Because JWTs can be signed—for example, using public/private key pairs—you can be sure the senders are who they say they are.
Create an HttpOnly cookie if JWT is persisted on the cookie to restrict third-party JavaScript from reading the JWT token from the cookie.
If a JWT token hasn’t expired and it lands in the wrong hands, that could lead to exploits. Building a token revocation list on your server to invalidate tokens once users have left your site could help tighten security.
Always use HTTPS to secure the authorization headers.
Chinedu is a tech enthusiast focused on full-stack JavaScript and Infrastructure engineering.