Home/Blog/How to Decode a JWT in Python
JWT · Python

How to Decode a JWT in Python

4 min readUpdated April 2026Developer Tools
Need to read the contents of a JWT token in Python? This guide covers three approaches — manual base64 decoding, using PyJWT, and using python-jose — with working code examples.

JWT Decoder

Decode any JWT instantly in your browser — no library needed. See header, payload, and expiry.

Open JWT Decoder →

Method 1 — Manual base64 decoding (no library)

A JWT payload is just Base64URL-encoded JSON. You can decode it without any external library:

Python
import base64
import json

def decode_jwt_payload(token: str) -> dict:
    # Split the token into parts
    parts = token.split('.')
    if len(parts) != 3:
        raise ValueError("Invalid JWT format")

    # Decode header and payload (add padding if needed)
    def decode_part(part):
        padding = 4 - len(part) % 4
        if padding != 4:
            part += '=' * padding
        decoded = base64.urlsafe_b64decode(part)
        return json.loads(decoded)

    header  = decode_part(parts[0])
    payload = decode_part(parts[1])
    return {"header": header, "payload": payload}

# Usage
token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJleHAiOjk5OTk5OTk5OTl9.signature"
result = decode_jwt_payload(token)
print(result["payload"]["sub"])  # "123"
print(result["payload"]["exp"])  # expiry timestamp
Note: This decodes the payload but does NOT verify the signature. Only use this for inspection — never trust a decoded JWT without server-side signature verification.

Method 2 — PyJWT (recommended for production)

PyJWT is the standard library for JWT handling in Python — decoding, encoding, and verification:

Install
pip install PyJWT
Decode without verification (inspection only)
import jwt

token = "your.jwt.token"

# Decode without verifying signature
payload = jwt.decode(
    token,
    options={"verify_signature": False}
)
print(payload)  # {'sub': '123', 'name': 'Ada', 'exp': 9999999999}
Decode WITH signature verification
import jwt

try:
    payload = jwt.decode(
        token,
        key="your-secret-key",   # or RSA public key
        algorithms=["HS256"]      # specify expected algorithm
    )
    user_id = payload["sub"]
    print(f"Valid token for user: {user_id}")

except jwt.ExpiredSignatureError:
    print("Token has expired")
except jwt.InvalidTokenError as e:
    print(f"Invalid token: {e}")

Checking JWT expiry in Python

Python
import time
import base64, json

def is_token_expired(token: str) -> bool:
    parts = token.split('.')
    payload_b64 = parts[1] + '=' * (4 - len(parts[1]) % 4)
    payload = json.loads(base64.urlsafe_b64decode(payload_b64))

    exp = payload.get('exp')
    if exp is None:
        return False  # No expiry set
    return time.time() > exp

if is_token_expired(token):
    print("Token is expired — redirect to login")

Decoding JWTs in Django / FastAPI

Both frameworks have built-in or plug-in JWT support:

FastAPI — python-jose
from jose import jwt, JWTError

SECRET_KEY = "your-secret-key"
ALGORITHM  = "HS256"

def get_current_user(token: str):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        user_id = payload.get("sub")
        return user_id
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

Frequently asked questions

What's the difference between PyJWT and python-jose?
PyJWT is simpler and more focused — good for most use cases. python-jose supports a broader range of algorithms and the full JOSE standard (JWE, JWK). FastAPI's documentation recommends python-jose. Either works for standard JWT decode use cases.
How do I decode a JWT with an RS256 (RSA) algorithm in Python?
Use the public key for decoding: jwt.decode(token, public_key, algorithms=["RS256"]). Load the public key from a PEM file using open("public.pem").read().
Can I decode a JWT without knowing the secret key?
You can decode (read) the header and payload without the secret key. You cannot verify the signature. Use options={{"verify_signature": False}} in PyJWT for inspection-only decoding.

Try it free — no sign-up needed

Runs entirely in your browser. Nothing uploaded, nothing stored.

Open JWT Decoder →

Related tools on tinybench.dev