JSON Web Token (JWT) Library
This is a JSON Web Token (JWT) library for Python 3, developed by GehirnInc, providing functionalities to encode and decode JWTs. It leverages the `cryptography` library for handling cryptographic operations, including key loading, signing, and verification. Version 1.4.0 is the latest stable release. It has a steady release cadence, focusing on stability and security rather than rapid feature development.
Warnings
- gotcha When decoding a JWT, you *must* explicitly provide a list of allowed algorithms (e.g., `algorithms=["RS256"]`) to `jwt.decode()`. Failing to do so will raise a `JWTVerificationError`, which is a critical security measure to prevent "none" algorithm attacks where an attacker could forge a token.
- gotcha The library expects specific key types. For symmetric algorithms (e.g., HS256), a `bytes` string secret is required. For asymmetric algorithms (e.g., RS256), `cryptography` key objects (e.g., `RSAPrivateKey` for encoding, `RSAPublicKey` for decoding) are needed. Passing the wrong type or format (e.g., a `str` for an HS256 secret) will lead to errors like `TypeError` or `JWSError`.
- gotcha Beyond signature verification, critical claims like `audience` (`aud`), `issuer` (`iss`), and `subject` (`sub`) should be explicitly validated during decoding. Use the corresponding arguments in `jwt.decode()` (e.g., `audience="your_app_id"`, `issuer="your_service"`). Failing to validate these can lead to security vulnerabilities such as token reuse or unauthorized access.
- gotcha As of v1.4.0, the `datetime_format` parameter was introduced to control how `datetime` objects in payloads are handled. By default, it expects Unix timestamps. If your payload uses Python `datetime.datetime` objects (especially for `exp`, `iat`, `nbf` claims), you must specify `datetime_format="datetime"` in both `jwt.encode()` and `jwt.decode()` to prevent conversion errors or unexpected behavior.
Install
-
pip install jwt
Imports
- jwt
import jwt
- encode
from jwt import encode
- decode
from jwt import decode
- JWTDecodeError
from jwt.exceptions import JWTDecodeError, JWTVerificationError
Quickstart
import jwt
import datetime
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
# --- Generate a key pair for demonstration (in a real app, load from secure storage) ---
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
# --- Encode a JWT ---
payload = {
"user_id": 123,
"username": "testuser",
"exp": datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=30),
"aud": "my-service-audience"
}
algorithm = "RS256"
# For a real application, private_key would be loaded from a secure source.
encoded_jwt = jwt.encode(
payload,
private_key,
algorithm=algorithm,
headers={"kid": "my_key_id"},
datetime_format="datetime" # Use "datetime" for `datetime` objects in payload
)
print("Encoded JWT:", encoded_jwt)
# --- Decode a JWT ---
# For a real application, public_key would be loaded from a secure source.
try:
decoded_jwt = jwt.decode(
encoded_jwt,
public_key,
algorithms=[algorithm], # REQUIRED: Must specify allowed algorithms
audience="my-service-audience", # RECOMMENDED: Validate audience
datetime_format="datetime"
)
print("\nDecoded JWT:", decoded_jwt)
except jwt.exceptions.JWTDecodeError as e:
print(f"\nError decoding JWT: {e}")
except Exception as e:
print(f"\nAn unexpected error occurred: {e}")