{"id":2087,"library":"jwt","title":"JSON Web Token (JWT) Library","description":"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.","status":"active","version":"1.4.0","language":"en","source_language":"en","source_url":"https://github.com/GehirnInc/python-jwt.git","tags":["jwt","json web token","security","cryptography","authentication"],"install":[{"cmd":"pip install jwt","lang":"bash","label":"Install jwt"}],"dependencies":[{"reason":"Required for all cryptographic operations (key loading, signing, verification).","package":"cryptography","optional":false}],"imports":[{"symbol":"jwt","correct":"import jwt"},{"symbol":"encode","correct":"from jwt import encode"},{"symbol":"decode","correct":"from jwt import decode"},{"note":"Common exceptions for handling decoding failures or verification errors.","symbol":"JWTDecodeError","correct":"from jwt.exceptions import JWTDecodeError, JWTVerificationError"}],"quickstart":{"code":"import jwt\nimport datetime\nfrom cryptography.hazmat.primitives import serialization\nfrom cryptography.hazmat.primitives.asymmetric import rsa\nfrom cryptography.hazmat.backends import default_backend\n\n# --- Generate a key pair for demonstration (in a real app, load from secure storage) ---\nprivate_key = rsa.generate_private_key(\n    public_exponent=65537,\n    key_size=2048,\n    backend=default_backend()\n)\npublic_key = private_key.public_key()\n\n# --- Encode a JWT ---\npayload = {\n    \"user_id\": 123,\n    \"username\": \"testuser\",\n    \"exp\": datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=30),\n    \"aud\": \"my-service-audience\"\n}\nalgorithm = \"RS256\"\n\n# For a real application, private_key would be loaded from a secure source.\nencoded_jwt = jwt.encode(\n    payload,\n    private_key,\n    algorithm=algorithm,\n    headers={\"kid\": \"my_key_id\"},\n    datetime_format=\"datetime\" # Use \"datetime\" for `datetime` objects in payload\n)\nprint(\"Encoded JWT:\", encoded_jwt)\n\n# --- Decode a JWT ---\n# For a real application, public_key would be loaded from a secure source.\ntry:\n    decoded_jwt = jwt.decode(\n        encoded_jwt,\n        public_key,\n        algorithms=[algorithm], # REQUIRED: Must specify allowed algorithms\n        audience=\"my-service-audience\", # RECOMMENDED: Validate audience\n        datetime_format=\"datetime\"\n    )\n    print(\"\\nDecoded JWT:\", decoded_jwt)\nexcept jwt.exceptions.JWTDecodeError as e:\n    print(f\"\\nError decoding JWT: {e}\")\nexcept Exception as e:\n    print(f\"\\nAn unexpected error occurred: {e}\")\n","lang":"python","description":"This example demonstrates how to encode and decode a JWT using an RSA key pair. It generates an in-memory key pair for illustration. Key elements include specifying the algorithm, handling `datetime` objects in the payload with `datetime_format`, and explicitly listing allowed algorithms and audience during decoding for security."},"warnings":[{"fix":"Always pass `algorithms=[...]` with the expected algorithm(s) to `jwt.decode()`.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your secret or key is of the correct Python type (`bytes` for symmetric, `cryptography` key object for asymmetric) and format corresponding to the chosen algorithm.","message":"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`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always pass relevant claim validation arguments (e.g., `audience`, `issuer`) to `jwt.decode()` to ensure the token is used in its intended context.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If using `datetime.datetime` objects in your payload claims, set `datetime_format=\"datetime\"` in both `encode` and `decode` calls. Otherwise, ensure `exp`, `iat`, `nbf` claims are Unix timestamps.","message":"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.","severity":"gotcha","affected_versions":">=1.4.0"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}