Introduction to JWTs

JWTs, or JSON Web Tokens, are a simple way of communicating information about a subject between two systems in a verifiable manner. They’re most commonly used as a form of authentication. For example, a single-page application may authenticate with an API using a JWT.

This article will offer a simple explanation of what a JWT is, and how it can be used to handle them confidently on your projects.

One of the best ways to get the details on specifications is to go to the source and read the RFC. You can often pull out missing or unclear tidbits from tutorials and blog posts. In the case of JWT, you might be surprised to learn that the suggestion pronunciation is “jot”!

What is a JWT?

A JWT is a URL-safe way of transferring claims between two parties, where a claim is an assertion about a subject.

Here’s an example of JWT.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiZW1haWwiOiJ0b20ucm9iZXJ0c2hhd0BzcGFjZTQ4LmNvbSIsImJjX2N1c3RvbWVyX2lkcyI6eyJ1cyI6NTQ2OSwiZ2IiOjI0OTIsImV1IjoxMDAyfSwiZXhwIjoxNzE1OTM1MzU2fQ.Ess20twQk7CJGdivxrg_dZNArpQMNAdt01hnM3fdbtc

While this looks indecipherable, with just a couple of steps we can make sense of it.

Firstly, a JWT has three parts: header, payload and signature, combined with a “.”

The Header

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

The header is base64 encoded. Once decoded, we can see that it includes metadata about the JWT such as which algorithm is used to generate the signature.

{
  "alg": "HS256",
  "typ": "JWT"
}

The Payload

eyJpZCI6MSwiZW1haWwiOiJ0b20ucm9iZXJ0c2hhd0BzcGFjZTQ4LmNvbSIsImJjX2N1c3RvbWVyX2lkcyI6eyJ1cyI6NTQ2OSwiZ2IiOjI0OTIsImV1IjoxMDAyfSwiZXhwIjoxNzE1OTM1MzU2fQ

The payload is also base64 encoded. Our JWT payload is:

{
   "id": 1,
   "email": "tom.robertshaw@***.com",
    "bc_customer_ids": {
       "us": 5469,
       "gb": 2492,
       "eu": 1002
   },
   "exp": 1715935356
}

The specification does not require any specific payload format, though there are some optional fields or “claims” that can be included like “exp” which we’ll discuss shortly.

Our payload represents a customer and their customer IDs in three BigCommerce stores. You could imagine that this JWT could be used as part of a single-sign-on mechanism across the stores.

The Signature

Ess20twQk7CJGdivxrg_dZNArpQMNAdt01hnM3fdbtc

The signature is a hash generated with the header, payload and a secret key. It can then be used to verify that the JWT has not been modified. As any modifications to the payload or header would result in the signature no longer matching and a new matching signature can only be created by a party with the shared secret key.

In our example, the header indicates that the signature is generated using the HMAC SHA256 algorithm. That tells us that we can verify using the following approach:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secretKey
)

Verifying the signature

When you receive a JWT, it’s essential to verify it to ensure it’s still valid. It may have been modified in transit, or have expired.

That’s incredibly simple to do, particularly with the jsonwebtoken package.

import jwt from "jsonwebtoken";

const payload = jwt.verify(jwtString, secretKey);

Choose JWE if you need confidentiality

One important note about our JWT is that the payload is readable by anyone. This type of JWT is a JSON Web Signature (JWS).

While the best policy is likely to avoid storing sensitive information in a JWT, if you need to, you can choose a JSON Web Encryption (JWE). With a JWE, the payload is encrypted before the signature is generated.

Standard Claims

There are no required properties for a JWT, however, the specification defines a list of optional claims.

"iss": "bc/apps",
"sub": "abc123",
"iat": 1480831863,
"nbf": 1480831863,
"exp": 1480832763,
"aud": "6sv16tfx3j5gsopm42ss5dd67g2srvq"
  • iss – The issuer
  • sub – The subject of the JWT, i.e. who the claims are about
  • iat – Issued at. A JWT should not be considered valid if the “issued at” is in the future
  • nbf – Not before. A JWT should be considered valid if the JWT is used before the “not before” time.
  • exp – Expires at. A JWT should be considered valid if it’s used after the expiry time.
  • aud – A reference to the expected audience, e.g. API client.

The benefits of JWTs

One of the main reasons that JWTs have become popular is because they are simple to use and are stateless. When compared to traditional cookie session management you need a central session store that is accessible by all web servers. This makes it more difficult to scale horizontally.

JWTs can be verified without a central session store and are well suited to cloud-based environments and function-as-a-service platforms.

To learn more about JWTs in practice, read our guide to JWTs in BigCommerce.

Tom Robertshaw
Stay up to date with Hypa news and features