Sharing is caring 🙂

Welcome to this tutorial on using JWT (JSON Web Tokens) in Python! In this guide, we will cover the basics of JWT and provide an example of using JWT in Python. We will also introduce the Python JWT module and go over the process of signing and verifying JWT tokens. Additionally, we will discuss techniques for decoding JWT tokens and explore options for working with and refreshing JWT tokens in Python. By the end of this tutorial, you should have a solid understanding of how to use JWT in your Python projects.

An Example of Using JWT in Python

To provide an example of using JWT in Python, let’s consider a simple example where we want to authenticate a user using a JWT. First, we will need to import the necessary modules and set up our JWT secret:

import jwt
import datetime

SECRET = "my-secret"

Next, we can create a function that takes a username and password as input and returns a JWT token if the credentials are valid:

def authenticate(username, password):
    if username == "admin" and password == "password":
        # Create a JWT token with a subject claim "admin" and an expiration time of 1 hour
        payload = {"sub": "admin", "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)}
        token = jwt.encode(payload, SECRET, algorithm="HS256")
        return token
    else:
        return None

We can then use this function to authenticate a user by calling it with the desired username and password:

token = authenticate("admin", "password")
print(token)  # b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

This simple example demonstrates how to use JWT in Python to authenticate a user and generate a JWT token. In a real-world application, the authenticate function would likely need to check the provided credentials against a database or other external resource.

The Python JWT Module

The Python JWT module is a library for generating and verifying JSON Web Tokens (JWT) in Python. It is built on top of the JWT, JWS, and JWK specifications and supports a number of cryptographic algorithms, including HMAC, RSA, and ECDSA.

To use the Python JWT module, you will need to install it first. You can do this using pip:

pip install pyjwt

Once installed, you can import the jwt module in your Python code:

import jwt

The jwt module provides a number of functions for working with JWT, including functions for encoding and decoding JWT, verifying JWT signatures, and generating and parsing JWKs (JSON Web Keys).

Here are some examples of using the Python JWT module:

# Encode a JWT with a subject claim and an expiration time
payload = {"sub": "admin", "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)}
secret = "my-secret"
token = jwt.encode(payload, secret, algorithm="HS256")

# Decode a JWT and print the subject claim
decoded = jwt.decode(token, secret, algorithms=["HS256"])
print(decoded["sub"])  # "admin"

# Verify a JWT signature
jwt.decode(token, secret, verify=True, algorithms=["HS256"])

This is just a brief overview of the Python JWT module and its capabilities.

Signing a JWT in Python

To sign a JWT in Python, you can use the encode function provided by the Python JWT module. This function takes a payload, a secret, and an algorithm as input and returns the signed JWT as a bytes object.

Here is an example of signing a JWT in Python using the HS256 algorithm:

import jwt

# Set the secret and the payload
secret = "my-secret"
payload = {"sub": "admin", "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)}

# Sign the JWT using the HS256 algorithm
token = jwt.encode(payload, secret, algorithm="HS256")
print(token)  # b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

In this example, we set the payload to include a subject claim “admin” and an expiration time of 1 hour from the current time. The encode function signs the payload with the provided secret and returns the resulting JWT as a bytes object.

You can use different algorithms by specifying them as the algorithm argument to the encode function. For example, to sign the JWT using the RS256 algorithm, you can use the following code:

import jwt
from jwt.algorithms import RSAAlgorithm

# Set the secret (a private RSA key) and the payload
secret = open("private.pem", "r").read()
payload = {"sub": "admin", "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)}

# Sign the JWT using the RS256 algorithm
token = jwt.encode(payload, secret, algorithm=RSAAlgorithm.RS256)
print(token)

The secret used for signing the JWT should be kept private and should not be shared with anyone who is not authorized to verify the JWT.

Setting the Expiration Time for a JWT in Python

To set the expiration time for a JWT in Python, you can include an “exp” (expiration) claim in the JWT payload. The value of this claim should be a datetime object representing the time at which the JWT will expire.

Here is an example of how to set the expiration time for a JWT in Python:

import jwt
import datetime

# Set the secret and the payload with an expiration time of 1 hour from the current time
secret = "my-secret"
payload = {"sub": "admin", "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)}

# Sign the JWT using the HS256 algorithm
token = jwt.encode(payload, secret, algorithm="HS256")
print(token)  # b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

In this example, we set the expiration time to 1 hour from the current time by using the datetime.timedelta function to calculate the difference between the current time and the desired expiration time. The resulting datetime object is then included in the payload as the “exp” claim.

When the JWT is verified, the verifier can check the expiration time to ensure that the JWT has not yet expired. If the current time is after the expiration time specified in the JWT, the JWT is considered invalid.

It is worth noting that the expiration time should be set based on the requirements of your application. A JWT with a very short expiration time may require frequent refreshing, while a JWT with a long expiration time may be vulnerable to attack if the secret is compromised. It is important to find a balance that meets the security needs of your application.

Verifying a JWT in Python

To verify a JWT in Python, you can use the decode function provided by the Python JWT module. This function takes a JWT, a secret, and a list of algorithms as input and returns the decoded JWT payload if the signature is valid.

Here is an example of how to verify a JWT in Python using the HS256 algorithm:

import jwt

# Set the secret and the JWT
secret = "my-secret"
token = b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

# Verify the JWT and print the subject claim
decoded = jwt.decode(token, secret, algorithms=["HS256"])
print(decoded["sub"])  # "admin"

In this example, we set the secret and the JWT we want to verify. We then call the decode function with the secret and the list of algorithms that we want to allow (in this case, only the HS256 algorithm is allowed). If the signature is valid, the decode function returns the decoded JWT payload. In this case, the subject claim “admin” is printed.

The function will raise an exception if the signature is invalid or if the JWT is expired (if an “exp” claim is included in the payload). You can catch this exception and handle it appropriately in your code.

You can also use the decode function to verify the signature of a JWT while ignoring the expiration time by setting the verify_exp parameter to False:

import jwt

# Set the secret and the JWT
secret = "my-secret"
token = b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

# Verify the JWT and print the subject claim, ignoring the expiration time
decoded = jwt.decode(token, secret, verify_exp=False, algorithms=["HS256"])
print(decoded["sub"])  # "admin"

This can be useful in cases where you want to verify the signature of a JWT without checking the expiration time. However, it is generally a good idea to verify the expiration time of a JWT to ensure that it is still valid.

Decoding a JWT in Python

To decode a JWT in Python, you can use the decode function provided by the Python JWT module. This function takes a JWT, a secret, and a list of algorithms as input and returns the decoded JWT payload if the signature is valid.

Here is an example of how to decode a JWT in Python using the HS256 algorithm:

import jwt

# Set the secret and the JWT
secret = "my-secret"
token = b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

# Decode the JWT and print the subject claim
decoded = jwt.decode(token, secret, algorithms=["HS256"])
print(decoded["sub"])  # "admin"

In this example, we set the secret and the JWT that we want to decode. We then call the decode function with the secret and the list of algorithms we want to allow (in this case, only the HS256 algorithm is allowed). If the signature is valid, the decode function returns the decoded JWT payload. In this case, the subject claim “admin” is printed.

If the signature is invalid or if the JWT is expired (if an “exp” claim is included in the payload), the decode function will raise an exception. You can catch this exception and handle it appropriately in your code.

Keep in mind that decoding a JWT does not verify the signature of the JWT. To verify the signature of a JWT, you should use the decode function with the verify parameter set to True.

import jwt

# Set the secret and the JWT
secret = "my-secret"
token = b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

# Decode and verify the JWT, and print the subject claim
decoded = jwt.decode(token, secret, verify=True, algorithms=["HS256"])
print(decoded["sub"])  # "admin"

This will ensure that the JWT has not been tampered with and that it has been signed with the correct secret.

Decoding a JWT Without a Secret in Python

To decode a JWT without a secret in Python, you can use the decode function provided by the Python JWT module, but you will need to pass the verify parameter as False. This will allow you to decode the JWT payload without verifying the signature of the JWT.

Here is an example of how to decode a JWT without a secret in Python:

import jwt

# Set the JWT
token = b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

# Decode the JWT without verifying the signature, and print the subject claim
decoded = jwt.decode(token, verify=False)
print(decoded["sub"])  # "admin"

In this example, we set the JWT that we want to decode. We then call the decode function with the verify parameter set to False, which allows us to decode the JWT payload without a secret. The decode function returns the decoded JWT payload, and the subject claim “admin” is printed.

Working with JWT Tokens in Python

To work with JWT tokens in Python, you can use the Python JWT module, which provides a number of functions for generating, signing, and verifying JWT tokens.

Here are some examples of working with JWT tokens in Python:

import jwt
import datetime

# Set the secret and the payload
secret = "my-secret"
payload = {"sub": "admin", "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)}

# Sign the JWT using the HS256 algorithm
token = jwt.encode(payload, secret, algorithm="HS256")
print(token)  # b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYWRtaW4iLCAiZXhwIjogMTU4NjQ1ODI5NX0.0zY4Y-4k4pWOaq8lFZN1C3J3qkm3x7zM26vjbWWYtZk'

# Decode and verify the JWT, and print the subject claim
decoded = jwt.decode(token, secret, verify=True, algorithms=["HS256"])
print(decoded["sub"])  # "admin"

# Check the expiration time of the JWT
if datetime.datetime.utcnow() > decoded["exp"]:
    print("JWT has expired")

In this example, we set the secret and the payload for the JWT. We then use the encode function to sign the JWT using the HS256 algorithm. The encode function returns the signed JWT as a bytes object.

We then use the decode function to decode and verify the JWT, and we print the subject claim. Finally, we check the expiration time of the JWT by comparing the current time to the expiration time included in the payload.

How To Refresh a JWT Token in Python

To refresh a JSON Web Token (JWT) in Python, you will need to perform the following steps:

  1. First, you will need to decode the JWT using the jwt library or any other library that allows you to decode JWTs. This will give you access to the claims (payload) of the JWT, including the expiration time (exp).
  2. Check if the JWT has expired by comparing the current time with the expiration time. If the JWT has not yet expired, you can simply return it as is.
  3. If the JWT has expired, you will need to request a new JWT from the authentication server. This can be done using an HTTP request, such as a POST request to the server’s refresh token endpoint.
  4. If the refresh request is successful, the server will return a new JWT. You can then return this new JWT to the client.

Here is an example of how this could be implemented in Python using the requests library:

import jwt
import requests
import time

# Replace these with your own values
auth_server_url = 'https://example.com/auth'
refresh_token = 'your_refresh_token'

def refresh_jwt(jwt):
  # Decode the JWT to get the expiration time
  claims = jwt.decode(jwt, verify=False)
  exp = claims['exp']

  # Check if the JWT has expired
  if time.time() > exp:
    # The JWT has expired, so request a new one using the refresh token
    refresh_response = requests.post(auth_server_url + '/refresh', json={'refresh_token': refresh_token})

    # If the refresh request was successful, return the new JWT
    if refresh_response.status_code == 200:
      return refresh_response.json()['access_token']
  else:
    # The JWT has not yet expired, so return it as is
    return jwt

This example assumes that the authentication server has a /refresh endpoint that accepts a refresh token and returns a new JWT in the response. You will need to modify this code to fit the specific requirements of your authentication server.

Sharing is caring 🙂