JWT Decoded: A Guide

JSON web token (JWT) is an open standard used to safely share encrypted information between a client and a server. Learn how to decode JWT using Python.

Written by Dinesh Kumar K.B.
Published on May. 07, 2024
JWT Decoded: A Guide
Image: Shutterstock / Built In
Brand Studio Logo

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. This enables the claims to be digitally signed or integrity protected with a message authentication code (MAC) and/or encryption.

What Is JWT? 

JSON web token (JWT) is a secure means of representing claims transferred between two parties, often a client and server. Claims are encoded as a JSON object containing a set of claims and a signature. It can be decoded in Python using multiple libraries, including python-jose and PyJWT.  

In other words, JWT is an open standard used to share information between two parties securely — a client and a server. In most cases, it’s an encoded JSON containing a set of claims and a signature. 

Python provides multiple libraries to encode and decode JSON web tokens. Let’s look at a couple of these libraries:

 

How to Encode JWT Using PyJWT

Let’s start with using PyJWT as the library.

Encode

import jwt


def encode_user():
    """
    encode user payload as a jwt
    :param user:
    :return:
    """
    encoded_data = jwt.encode(payload={"name": "Dinesh"},
                              key='secret',
                              algorithm="HS256")

    return encoded_data


if __name__ == "__main__":
    print(encode_user())

Output

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiRGluZXNoIn0.7Fwj-RvoEP2-LfB5q05pdTvMl7pFpoQgwXYq3EOLens


Process finished with exit code 0

The code above is self-explanatory. We have a payload as a Python dict, i.e. the data to be encoded, and a secret key used to encode. Also, we have used the algorithm HS256 for signing the token. The algorithms supported by PyJWT are provided on its site.

More on JSONHow to Use JSON.stringify() and JSON.parse() in JavaScript

 

How to Decode JWT

Let’s try and understand the structure of a JWT token. A JWT token typically contains a user’s claims. These represent data about the user, which the API can use to grant permissions or trace the user providing the token. The different components of a JWT token are separated with a period(.). A JWT token consists of three parts. Each section is comprised of base64url-encoded JSON containing specific information for that token:

  1. Header
  2. Payload
  3. Signature

jwt.io can also be used to decode a JWT token, breaking it into the components above.

Screenshot of Jwt.io used to decode a JWT token.
Screenshot of Jwt.io used to decode a JWT token. | Screenshot: Dinesh Kumar K.B.

Decode

import jwt


def decode_user(token: str):
    """
    :param token: jwt token
    :return:
    """
    decoded_data = jwt.decode(jwt=token,
                              key='secret',
                              algorithms=["HS256"])

    print(decoded_data)

Output

/Users/dkb/VirtualEnvs/py3.11-env/bin/python3.11 /Users/dkb/Code/practice/my_jwt.py

{'name': 'Dinesh'}

Process finished with exit code 0
A tutorial on how to decode a JWT. | Video: Michael Bissell

More on JSONHow to Use JSON Schema to Validate Documents in Python

 

How to Decode a JWT Using a Public Key

A public key can be used to decode a JWT. Usually these public keys should be made available to tenants using the uniform resource identifier (URI) format below. Every open ID server has to provide this endpoint. In our case, the public key is called as a JSON web key (JWK).

JWK is a JSON object that contains a well-known public key that can be used to validate the signature of a signed JWT.

If the issuer of your JWT used an asymmetric key to sign the JWT, it will likely host a file called a JSON web key set (JWKS). The JWKS is a JSON object that contains the property keys, which in turn holds an array of JWK objects.

 https://--YOUR DOMAIN----/.well-known/jwks.json


Sample Response:

{
  keys: [
    {
      alg: 'RS256',
      kty: 'RSA',
      use: 'sig',
      n: 'tTMpnrc4dYlD8MtmPnW3xZNbLxkaGCUwTqeKB4dfLg11dEpMyQEc4JRxUvRzp9tz00r6lkZ1ixcvIiuB_eMVckU8VyFSFWBSAxp5duBk6lRpYk-QjK3kEdPxYLxyW84gNzwMi-XW8zxJbsOa-cRM9sCb62Qz2yfWoQfimoFXsCnVHq496kizO7gZ972JefvTce1_n9dd_1p0K6c14qcCXtF6hbA_gQ0N7h3IyloBqiusKyTsV-ZrMZDldZkI-4v7s49TdcRZgEOvSapMz5YyoDvAWzuWGEiljkjkCOo0Mr5Sioi2x0dBm6nJ2WVYfZrwEF5J',
      e: 'AQAB',
      kid: 'NTY2MjBCNzQ1RTLPQzk3NzczRRTMQ0E4NzE2MjcwOUFCRkUwRTUxNA',
      x5t: 'NTY2MjBCNzQ1RTJPLzk3NzczRUNPO0E4NzE2MjcwOUFCRkUwRTUxNA',
      x5c: [Array]
    }
  ]
}

Now, let’s write a Python code to decode a JWT token using python-jose.

import jwt
import httpx


def decode_access_token(authorisation_token):

    # get public key from jwks uri
    response = httpx.get(url="your open id wellknown url to fetch public key")

    # gives the set of jwks keys.the keys has to be passed as it is to jwt.decode() for signature verification.
    key = response.json()

    # get the algorithm type from the request header
    algorithm = jwt.get_unverified_header(authorisation_token).get('alg')

    user_info = jwt.decode(token=authorisation_token,
                           key=key,
                           algorithms=algorithm)

    return user_info

I used python-jose here just to show that there is no significant difference between these libraries. python-jose is a wrapper on top of PyJWT

 The reason I have mentioned both libraries is that sometimes your build pipeline like Gitlab/Jenkins complains about having incompatible versions of cryptography with PyJWT. However, python-jose offers a quick solution in those scenarios without requiring you to change the code. 

And the code doesn’t look much different from PyJWT, does it?

With all this in mind, remember that anyone can decode the information contained in a JWT without knowing the private keys. For this reason, you should never put secret information like passwords or cryptographic keys in a JWT.

Hiring Now
Arcadia
Big Data • Healthtech • Software • Analytics
SHARE