JWT · Python
How to Decode a JWT in Python
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 timestampNote: 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 →