Skip to main content

JWT Tokens

One of the important concepts in web security is JWT (pronounced "jot"). As an API developer, test engineer or integration specialist, if you haven't heard about JWT, you are missing the most required knowledge. JWT is a proven mechanism for secure communication, authentication and authorisation. In this article, we'll delve deep into JWT Tokens, unraveling their workings, benefits, and best practices to adopt.

What Are JWT Tokens?

By definition, JSON Web Token is a URL-safe and compact means of representing claims to be transferred between two systems. The information transmitted can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

A JWT typically looks like the following.

[header].[payload].[signature]

Here is a sample value of JWT token and how it is being sent in Authorization in an HTTP request:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzNDU2Nzg5LCJuYW1lIjoiSm9zZXBoIn0.OpOSSw7e485LOP5PrzScxHb7SR6sAOMRckfFwi4rp7o

Here, all the three components are Based64 encoded. Let's break down these below.

  • Header: This section identifies the token type (JWT) and the signing algorithm. If you decode this component, you will get {"alg":"HS256","typ":"JWT"}.
  • Payload: The payload contains the claims. Claims are statements about an entity (typically, the user) and additional data. In the above example, the decoded value of the middle component is {"id":123456789,"name":"Joseph"} and it represents the claim.
  • Signature: This is a claim, prevent tampering. It is built as a signature of header and payload. This component is a binary value when decoded.

How JWT Tokens Work

The process begins with the server generating a token that encapsulates the user’s identity and granting permissions. When a user logs in, the server creates a JWT and sends it back. This token must be included in the header of any future requests, allowing the server to verify the user's identity without needing to access a database.

Benefits of Using JWT Tokens

  • Statelessness: JWTs are self-contained, carrying all necessary information about the user. This makes the application scalable as it doesn’t require a session store.
  • Security: The information is digitally signed, ensuring the data has not been altered.
  • Cross-Platform: JWTs can be used in any part of an application, whether it be a mobile app, a web app, or even IoT devices.

Implementing JWT Tokens

To implement JWT in your application, you'll need a library that supports JWT creation and verification. Here are some popular JWT libraries for various programming languages:

LanguageLibrary Name & Link
JavaJJWT
Node.jsauth0/jsonwebtoken
JavaScriptauth0/jwt-decode
PHPfirebase/php-jwt
PythonPyJWT
Rubyjwt
Gogolang-jwt/jwt
C#jwt-dotnet
Swiftauth0/JWTDecode
RustKeats/jsonwebtoken

Here's a simplified process and data flow:

  1. Install a JWT library compatible with your tech stack.
  2. Upon user login, generate a JWT token and send it back to the client.
  3. In subsequent requests, the client includes this token in the header.
  4. The server verifies the token and allows access to protected resources.

JWT Best Practices

  • Keep the payload minimal to reduce the size of the token.
  • Implement token expiration to mitigate the risk of stolen tokens.
  • Protect your application against XSS and CSRF attacks by properly handling token storage and transmission.

Handling Logout

A secure logout is a must for any web application. Achieving this with JWT tokens is a challenging task due to their stateless nature. This is the only complexity they bring when you adopt JWTs. Since JWT tokens are self-contained and carry all the necessary information within themselves, revoking a token once it has been issued is not straightforward.

Here are a couple of approaches that can be employed to handle logout effectively:

Server-side Token Blacklisting

One approach to invalidating JWT tokens upon logout is to maintain a server-side blacklist of revoked tokens. When a user logs out, the server adds the token to the blacklist, and subsequent requests with that token are rejected. This method ensures that even if a token is unexpectedly compromised, it can be quickly invalidated on the server-side.

To implement this approach:

  1. Set up a database or cache to store the blacklisted tokens and their expiration times.
  2. When a user logs out, retrieve the token from the request and add it to the blacklist along with the current timestamp and the token's original expiration time.
  3. Before processing any request, check if the token is present in the blacklist. If it is, reject the request.
  4. Periodically clean up the blacklist by removing expired tokens to save storage space and improve performance.
  5. While effective, this method requires additional server-side resources and complexity to maintain the blacklist.

Client-side Token Expiration

Another approach is to enforce token expiration on the client-side by setting a short expiration time for the JWT tokens. When a user logs out, the client can simply discard the token, and subsequent requests will fail due to the token's expiration.

To implement this approach:

  1. Set a short expiration time for the JWT tokens, such as a few minutes or hours, depending on your application's requirements.
  2. When a user logs out, discard the token on the client-side (e.g., remove it from local storage or cookies).
  3. When an expired token is used in an HTTP request, the server will reject it, and the client can handle this rejection by forcing the user to login in again.
  4. This method is simpler to implement and doesn't require additional server-side resources, but it relies on the client to properly handle token expiration and logout scenarios.

JWT Tokens are a powerful tool in the arsenal of web security, offering both flexibility and robust protection. By understanding and implementing JWT according to the best practices outlined, you can significantly enhance the security and user experience of your applications.