Try it yourself with our free Jwt Decoder tool — runs entirely in your browser, no signup needed.

How to Verify JWT token signatures in Python

How to Verify JWT Token Signatures in Python

Verifying JWT token signatures is a crucial step in ensuring the authenticity and integrity of data exchanged between systems. In this guide, we will walk through the process of verifying JWT token signatures in Python, providing a quick example, step-by-step breakdown, edge case handling, common mistakes, performance tips, and frequently asked questions.

Quick Example

import jwt

def verify_jwt_token(token, secret_key):
    try:
        payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        return payload
    except jwt.ExpiredSignatureError:
        return "Token has expired"
    except jwt.InvalidTokenError:
        return "Invalid token"

# Example usage:
token = "your_jwt_token_here"
secret_key = "your_secret_key_here"
print(verify_jwt_token(token, secret_key))

This code snippet verifies a JWT token using the HS256 algorithm and returns the payload if the token is valid.

Step-by-Step Breakdown

Let's break down the code:

import jwt

We import the jwt library, which is a popular and well-maintained library for working with JWTs in Python. You can install it using pip: pip install PyJWT.

def verify_jwt_token(token, secret_key):

We define a function verify_jwt_token that takes two arguments: token (the JWT token to verify) and secret_key (the secret key used to sign the token).

try:
    payload = jwt.decode(token, secret_key, algorithms=['HS256'])
    return payload

We use the jwt.decode function to verify the token. We pass the token, secret_key, and a list of algorithms (['HS256']) to the function. If the token is valid, the function returns the payload.

except jwt.ExpiredSignatureError:
    return "Token has expired"
except jwt.InvalidTokenError:
    return "Invalid token"

We catch two types of exceptions: ExpiredSignatureError (raised when the token has expired) and InvalidTokenError (raised when the token is invalid). We return a corresponding error message for each exception.

Handling Edge Cases

Empty/Null Input

def verify_jwt_token(token, secret_key):
    if not token or not secret_key:
        raise ValueError("Token and secret key cannot be empty")
    # ...

We add a simple check to raise a ValueError if either the token or secret_key is empty.

Invalid Input

def verify_jwt_token(token, secret_key):
    try:
        payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        # ...
    except jwt.InvalidTokenError:
        return "Invalid token"

We catch the InvalidTokenError exception and return an error message if the token is invalid.

Large Input

def verify_jwt_token(token, secret_key):
    try:
        payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        # ...
    except jwt.DecodeError:
        return "Failed to decode token"

We catch the DecodeError exception, which is raised when the token is too large to decode.

Unicode/Special Characters

def verify_jwt_token(token, secret_key):
    try:
        payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        # ...
    except jwt.InvalidTokenError:
        return "Invalid token"

We catch the InvalidTokenError exception, which is raised when the token contains invalid characters.

Common Mistakes

Mistake 1: Using the Wrong Algorithm

Wrong code:

jwt.decode(token, secret_key, algorithms=['RS256'])

Corrected code:

jwt.decode(token, secret_key, algorithms=['HS256'])

Make sure to use the correct algorithm (HS256 in this case) when decoding the token.

Mistake 2: Not Handling Exceptions

Wrong code:

payload = jwt.decode(token, secret_key, algorithms=['HS256'])

Corrected code:

try:
    payload = jwt.decode(token, secret_key, algorithms=['HS256'])
except jwt.ExpiredSignatureError:
    return "Token has expired"
except jwt.InvalidTokenError:
    return "Invalid token"

Always handle exceptions when decoding the token to catch errors.

Mistake 3: Not Validating Input

Wrong code:

def verify_jwt_token(token, secret_key):
    payload = jwt.decode(token, secret_key, algorithms=['HS256'])
    return payload

Corrected code:

def verify_jwt_token(token, secret_key):
    if not token or not secret_key:
        raise ValueError("Token and secret key cannot be empty")
    try:
        payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        return payload
    except jwt.ExpiredSignatureError:
        return "Token has expired"
    except jwt.InvalidTokenError:
        return "Invalid token"

Always validate the input (token and secret key) before decoding the token.

Performance Tips

  1. Use a fast algorithm: The HS256 algorithm is faster than RS256, so use it if possible.
  2. Use a cached secret key: If you're verifying multiple tokens with the same secret key, cache the secret key to avoid recalculating it.
  3. Use a Just-In-Time (JIT) compiler: JIT compilers like PyPy can significantly improve performance for CPU-bound tasks like token verification.

FAQ

Q: What is the difference between HS256 and RS256 algorithms?

A: HS256 uses a secret key to sign the token, while RS256 uses a public-private key pair.

Q: Can I use a different algorithm for token verification?

A: Yes, but make sure to use a secure algorithm like HS256 or RS256.

Q: How do I handle token expiration?

A: Catch the ExpiredSignatureError exception and return an error message.

Q: Can I use this code for token generation as well?

A: No, this code is for token verification only. Use a separate library or function for token generation.

Q: Is this code secure?

A: Yes, this code uses secure practices and libraries to verify JWT tokens. However, always follow best practices for security and testing.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp