### Install PyJWT Source: https://github.com/jpadilla/pyjwt/blob/master/docs/installation.md Use this command to install the PyJWT library. ```console pip install pyjwt ``` -------------------------------- ### OIDC Login Flow Setup and Configuration Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Demonstrates the initial setup for an OIDC login flow. It involves fetching OIDC configuration and JWKS, and initializing PyJWKClient. Requires client_id and oidc_server to be defined. ```python import base64 import jwt import requests # Part 1: setup # get the OIDC config and JWKs to use # in OIDC, you must know your client_id (this is the OAuth 2.0 client_id) client_id = ... # example of fetching data from your OIDC server # see: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig oidc_server = ... oidc_config = requests.get( f"https://{oidc_server}/.well-known/openid-configuration" ).json() signing_algos = oidc_config["id_token_signing_alg_values_supported"] # setup a PyJWKClient to get the appropriate signing key jwks_client = jwt.PyJWKClient(oidc_config["jwks_uri"]) ``` -------------------------------- ### Install PyJWT via pip Source: https://github.com/jpadilla/pyjwt/blob/master/README.rst Use the pip package manager to install the library. ```console $ pip install PyJWT ``` -------------------------------- ### Install PyJWT with Cryptographic Dependencies Source: https://github.com/jpadilla/pyjwt/blob/master/docs/installation.md Install PyJWT with optional cryptographic dependencies for RSA and ECDSA algorithms. This is recommended for requirements files. ```console pip install pyjwt[crypto] ``` -------------------------------- ### Fetch JWK signing key from JWKS endpoint and decode JWT Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst This example demonstrates how to use PyJWKClient to fetch signing keys from a JWKS URL and then decode a JWT using the appropriate key and algorithm. It bypasses expiration verification. ```python import jwt from jwt import PyJWKClient token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRTFRVVJCT1RNNE16STVSa0ZETlRZeE9UVTFNRGcyT0Rnd1EwVXpNVGsxUWpZeVJrUkZRdyJ9.eyJpc3MiOiJodHRwczovL2Rldi04N2V2eDlydS5hdXRoMC5jb20vIiwic3ViIjoiYVc0Q2NhNzl4UmVMV1V6MGFFMkg2a0QwTzNjWEJWdENAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vZXhwZW5zZXMtYXBpIiwiaWF0IjoxNTcyMDA2OTU0LCJleHAiOjE1NzIwMDY5NjQsImF6cCI6ImFXNENjYTc5eFJlTFdVejBhRTJINmtEME8zY1hCVnRDIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.PUxE7xn52aTCohGiWoSdMBZGiYAHwE5FYie0Y1qUT68IHSTXwXVd6hn02HTah6epvHHVKA2FqcFZ4GGv5VTHEvYpeggiiZMgbxFrmTEY0csL6VNkX1eaJGcuehwQCRBKRLL3zKmA5IKGy5GeUnIbpPHLHDxr-GXvgFzsdsyWlVQvPX2xjeaQ217r2PtxDeqjlf66UYl6oY6AqNS8DH3iryCvIfCcybRZkc_hdy-6ZMoKT6Piijvk_aXdm7-QQqKJFHLuEqrVSOuBqqiNfVrG27QzAPuPOxvfXTVLXL2jek5meH6n-VWgrBdoMFH93QEszEDowDAEhQPHVs0xj7SIzA" kid = "NEE1QURBOTM4MzI5RkFDNTYxOTU1MDg2ODgwQ0UzMTk1QjYyRkRFQw" url = "https://dev-87evx9ru.auth0.com/.well-known/jwks.json" jwks_client = PyJWKClient(url) signing_key = jwks_client.get_signing_key_from_jwt(token) data = jwt.decode( token, signing_key.key, algorithms=["RS256"], audience="https://expenses-api", options={"verify_exp": False}, ) print(data) ``` -------------------------------- ### Validate minimum key length for HMAC and RSA keys Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst This example shows how to enforce minimum key length validation for HMAC and RSA keys. By default, it warns about insecure key lengths. Passing `enforce_minimum_key_length=True` raises an `InvalidKeyError`. ```python jwt.encode(payload, key, algorithm="HS256", options={"enforce_minimum_key_length": True}) ``` -------------------------------- ### Encode JWT with HS512 Algorithm Source: https://github.com/jpadilla/pyjwt/blob/master/docs/algorithms.md Use the `algorithm` parameter in `jwt.encode()` to specify the signing algorithm. This example uses HS512. ```python encoded = jwt.encode({"some": "payload"}, "secret", algorithm="HS512") print(encoded) ``` -------------------------------- ### Encode JWT with JWK support Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Example of encoding a JWT payload using JWK (JSON Web Key) support. This feature allows for more flexible key management. ```python encoded_jwt = jwt.encode(payload, key=jwk_private_key, algorithm="RS256") ``` -------------------------------- ### Encode and Decode JWT with RS256 Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Use this snippet to encode a payload into a JWT using an RSA private key and RS256 algorithm, and then decode it using the corresponding public key. Ensure the `cryptography` module is installed. ```python import jwt private_key = b"-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAwhvqCC+37A+UXgcvDl+7nbVjDI3QErdZBkI1VypVBMkKKWHM\nNLMdHk0bIKL+1aDYTRRsCKBy9ZmSSX1pwQlO/3+gRs/MWG27gdRNtf57uLk1+lQI\n6hBDozuyBR0YayQDIx6VsmpBn3Y8LS13p4pTBvirlsdX+jXrbOEaQphn0OdQo0WD\noOwwsPCNCKoIMbUOtUCowvjesFXlWkwG1zeMzlD1aDDS478PDZdckPjT96ICzqe4\nO1Ok6fRGnor2UTmuPy0f1tI0F7Ol5DHAD6pZbkhB70aTBuWDGLDR0iLenzyQecmD\n4aU19r1XC9AHsVbQzxHrP8FveZGlV/nJOBJwFwIDAQABAoIBAFCVFBA39yvJv/dV\nFiTqe1HahnckvFe4w/2EKO65xTfKWiyZzBOotBLrQbLH1/FJ5+H/82WVboQlMATQ\nSsH3olMRYbFj/NpNG8WnJGfEcQpb4Vu93UGGZP3z/1B+Jq/78E15Gf5KfFm91PeQ\nY5crJpLDU0CyGwTls4ms3aD98kNXuxhCGVbje5lCARizNKfm/+2qsnTYfKnAzN+n\nnm0WCjcHmvGYO8kGHWbFWMWvIlkoZ5YubSX2raNeg+YdMJUHz2ej1ocfW0A8/tmL\nwtFoBSuBe1Z2ykhX4t6mRHp0airhyc+MO0bIlW61vU/cPGPos16PoS7/V08S7ZED\nX64rkyECgYEA4iqeJZqny/PjOcYRuVOHBU9nEbsr2VJIf34/I9hta/mRq8hPxOdD\n/7ES/ZTZynTMnOdKht19Fi73Sf28NYE83y5WjGJV/JNj5uq2mLR7t2R0ZV8uK8tU\n4RR6b2bHBbhVLXZ9gqWtu9bWtsxWOkG1bs0iONgD3k5oZCXp+IWuklECgYEA27bA\n7UW+iBeB/2z4x1p/0wY+whBOtIUiZy6YCAOv/HtqppsUJM+W9GeaiMpPHlwDUWxr\n4xr6GbJSHrspkMtkX5bL9e7+9zBguqG5SiQVIzuues9Jio3ZHG1N2aNrr87+wMiB\nxX6Cyi0x1asmsmIBO7MdP/tSNB2ebr8qM6/6mecCgYBA82ZJfFm1+8uEuvo6E9/R\nyZTbBbq5BaVmX9Y4MB50hM6t26/050mi87J1err1Jofgg5fmlVMn/MLtz92uK/hU\nS9V1KYRyLc3h8gQQZLym1UWMG0KCNzmgDiZ/Oa/sV5y2mrG+xF/ZcwBkrNgSkO5O\n7MBoPLkXrcLTCARiZ9nTkQKBgQCsaBGnnkzOObQWnIny1L7s9j+UxHseCEJguR0v\nXMVh1+5uYc5CvGp1yj5nDGldJ1KrN+rIwMh0FYt+9dq99fwDTi8qAqoridi9Wl4t\nIXc8uH5HfBT3FivBtLucBjJgOIuK90ttj8JNp30tbynkXCcfk4NmS23L21oRCQyy\nlmqNDQKBgQDRvzEB26isJBr7/fwS0QbuIlgzEZ9T3ZkrGTFQNfUJZWcUllYI0ptv\ny7ShHOqyvjsC3LPrKGyEjeufaM5J8EFrqwtx6UB/tkGJ2bmd1YwOWFHvfHgHCZLP\n34ZNURCvxRV9ZojS1zmDRBJrSo7+/K0t28hXbiaTOjJA18XAyyWmGg==\n-----END RSA PRIVATE KEY----- ``` ```python public_key = b"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwhvqCC+37A+UXgcvDl+7\nnbVjDI3QErdZBkI1VypVBMkKKWHMNLMdHk0bIKL+1aDYTRRsCKBy9ZmSSX1pwQlO\n/3+gRs/MWG27gdRNtf57uLk1+lQI6hBDozuyBR0YayQDIx6VsmpBn3Y8LS13p4pT\nBvirlsdX+jXrbOEaQphn0OdQo0WDoOwwsPCNCKoIMbUOtUCowvjesFXlWkwG1zeM\nzlD1aDDS478PDZdckPjT96ICzqe4O1Ok6fRGnor2UTmuPy0f1tI0F7Ol5DHAD6pZ\nbkhB70aTBuWDGLDR0iLenzyQecmD4aU19r1XC9AHsVbQzxHrP8FveZGlV/nJOBJw\nFwIDAQAB\n-----END PUBLIC KEY----- " ``` ```python encoded = jwt.encode({"some": "payload"}, private_key, algorithm="RS256") ``` ```python jwt.decode(encoded, public_key, algorithms=["RS256"]) ``` -------------------------------- ### Run project tests Source: https://github.com/jpadilla/pyjwt/blob/master/README.rst Execute the test suite from the project root directory. ```console $ tox ``` -------------------------------- ### Handle Insecure Key Length Warning Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Shows the default behavior when using a key that does not meet minimum length requirements. ```pycon >>> import jwt >>> encoded = jwt.encode({"some": "payload"}, "short", algorithm="HS256") ``` -------------------------------- ### Encode and Decode JWTs Source: https://github.com/jpadilla/pyjwt/blob/master/README.rst Demonstrates basic token creation and verification using a secret key and HS256 algorithm. ```pycon >>> import jwt >>> encoded = jwt.encode({"some": "payload"}, "secret", algorithm="HS256") >>> print(encoded) eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg >>> jwt.decode(encoded, "secret", algorithms=["HS256"]) {'some': 'payload'} ``` -------------------------------- ### Encode and Decode JWT with HS256 Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Demonstrates the basic workflow of creating a signed token and verifying it using a shared secret key. ```pycon >>> import jwt >>> key = "secret" >>> encoded = jwt.encode({"some": "payload"}, key, algorithm="HS256") >>> jwt.decode(encoded, key, algorithms="HS256") {'some': 'payload'} ``` -------------------------------- ### OIDC Login Flow: Token Handling and at_hash Validation Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Illustrates handling the token response from an OIDC login flow and validating the `at_hash` claim. This requires decoding the ID token, computing the `at_hash`, and comparing it with the payload. ```python import base64 import jwt import requests # Part 2: login / authorization # when a user completes an OIDC login flow, there will be a well-formed # response object to parse/handle # data from the login flow # see: https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse token_response = ... id_token = token_response["id_token"] access_token = token_response["access_token"] # Part 3: decode and validate at_hash # after the login is complete, the id_token needs to be decoded # this is the stage at which an OIDC client must verify the at_hash # get signing_key from id_token signing_key = jwks_client.get_signing_key_from_jwt(id_token) # now, decode_complete to get payload + header data = jwt.decode_complete( id_token, key=signing_key, audience=client_id, algorithms=signing_algos, ) payload, header = data["payload"], data["header"] # get the pyjwt algorithm object alg_obj = jwt.get_algorithm_by_name(header["alg"]) # compute at_hash, then validate / assert digest = alg_obj.compute_hash_digest(access_token) at_hash = base64.urlsafe_b64encode(digest[: (len(digest) // 2)]).rstrip("=") assert at_hash == payload["at_hash"] ``` -------------------------------- ### Use leeway with nbf claim Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Demonstrates how to use the 'leeway' option with the 'nbf' (not before) claim during JWT decoding. This allows for a small time window to account for clock skew. ```python decoded_token = jwt.decode(token, key, algorithms=["HS256"], leeway=10) ``` -------------------------------- ### Set and Retrieve Subject Claim Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Demonstrates encoding and decoding a JWT containing the optional 'sub' claim. ```pycon >>> payload = {"some": "payload", "sub": "1234567890"} >>> token = jwt.encode(payload, "secret") >>> decoded = jwt.decode(token, "secret", algorithms=["HS256"]) >>> decoded["sub"] '1234567890' ``` -------------------------------- ### Encode and Decode with PS256 (RSA) Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Use PS256 for RSA encoding and decoding. Requires the 'cryptography' module. Ensure your private and public keys are correctly formatted. ```python >>> import jwt >>> private_key = "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAuNhCS6bodtd+PvKqNj+tYZYqTNMDkf0rcptgHhecSsMP9Vay\n+6NvJk1tC+IajPaE4yRJVY4jFqEt3A0MJ9sKe5mWDYFmzW/L6VzQvQ+0nrMc1YTE\nDpOf7BQhlW5W0mDj5SwSR50Lxg/acb+SMWq6zmhuAoLRapH17K2RWONA2vr2frox\nJ6N9TGtrQHygDb0p9D6jPnXEe4y+zBuj6o0bCkJgCVNM+CU19xBepj5caetYV28/\n49yl5XPi93n1ATU+7aGAKxuvjudODuHhF/UsZScMFSHeZW367eQldTB2w9uoIIzW\nO46tKimr21zYifMimjwnBQ/PLDqc7HqY0Y/rLQIDAQABAoIBAAdu0CD7/Iu61/LE\nDfV8fgZXOYA5WVgSLCBsVbh1Y+2FsStBFJVrLwRanLCbo6GuJWMqNGC3ryWGebJI\nPAg7lfepEhBHodClAY1yvq9mOvHJa2Fn+KegEWWMMbAxQwCBW5NS6waXhBUE0i3n\ncYOB3TKA9IYuqH52kW22VQqT/imlWEb28pJJT49YfggmOOtAkrKerokO53lAfrJA\ntm8lYvxXnfnuYh7zI835RpZJ1PeaYrMqyAwT+StD9hPKGWGpN1gCJijjcK0aapvq\nMLET/JxMxxcLsINOeLtGhMKawmET3J/esJTumOE2L77MFG83rlCPbsSfLdSAI2WD\nSe3Q2ikCgYEA7JzmVrPh7G/oILLzIfk8GHFACRTtlE5SDEpFq+ARMprfcBXpkl+Q\naWqQ3vuSH7oiAQKlvo3We6XXohCMMDU2DyMaXiQMk73R83fMwbFnFcqFhbzx2zpm\nj/neHIViEi/N69SHPxl+vnUTfeVZptibNGS+8Jh5yrpHyljiIYwh/1y0WsbungMl\nH6lG9JigcN8R2Tk9hWT7DQL0fm0dYoQjkwr/gJv6PW0piLsR0vsQQpm/F/ucZolV\nPQIoisCgYA5XXzWznvax/LeYqRhuzxf rK1axlEnYKmxwxwLJKLmwvejBB0B2Nt5Q1XmSdXOjWELH6oxfc/fYIDcEOj8ExqNJvSQmGrYMvBA9+2TlEAq31Pp7boxbYJKK8k23vu87wwcvgUgPj0lTdsw7bcDpYZTeI1Xu3WyNUlVxJ6nm8IoZwKBgG6YPjVekKg+htrF4Tt58fa95E+X4JPVsBrBZqouFeN5WTTzUZ+odfNPxILVwC2BrTjbRgBvJPUcr6t4zWZQKxzKqHfrrt0kkDb0QHC2AHR8ScFc65NHtl5n3F+ZAJhjsGn3qeQnN4TGsEBx8C6XzXY4BDSLnhweqOvlxJNQSJ31AoGAX/UN5xR6PlCgPw5HWfGd7+4sArkjA36DAXvrAgW/6/mxZZzoGA1swYdZq2uGp38UEKkxKTrhR4J6eR5DsLAfl/KQBbNC42vqZwe9YrS4hNQFR14GwlyJhdLxKQD/JzHwNQN5+o+hy0lJavTw9NwAAb1ZzTgvq6fPwEG0b9hn0SI= -----END RSA PRIVATE KEY----- ``` ```python >>> public_key = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuNhCS6bodtd+PvKqNj+t\nYZYqTNMDkf0rcptgHhecSsMP9Vay+6NvJk1tC+IajPaE4yRJVY4jFqEt3A0MJ9sK\ne5mWDYFmzW/L6VzQvQ+0nrMc1YTEDpOf7BQhlW5W0mDj5SwSR50Lxg/acb+SMWq6\nzmhuAoLRapH17K2RWONA2vr2froxJ6N9TGtrQHygDb0p9D6jPnXEe4y+zBuj6o0b\nCkJgCVNM+CU19xBepj5caetYV28/49yl5XPi93n1ATU+7aGAKxuvjudODuHhF/Us\nZScMFSHeZW367eQldTB2w9uoIIzWO46tKimr21zYifMimjwnBQ/PLDqc7HqY0Y/r\nLQIDAQAB\n-----END PUBLIC KEY----- " ``` ```python >>> encoded = jwt.encode({"some": "payload"}, private_key, algorithm="PS256") ``` ```python >>> jwt.decode(encoded, public_key, algorithms=["PS256"]) {'some': 'payload'} ``` -------------------------------- ### Fetch JWKS and Decode JWT Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Use PyJWKClient to fetch signing keys from a JWKS URL and decode a JWT. Supports custom headers for the JWKS request. Caching is built-in. ```python import jwt from jwt import PyJWKClient token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRTFRVVJCT1RNNE16STVSa0ZETlRZeE9UVTFNRGcyT0Rnd1EwVXpNVGsxUWpZeVJrUkZRdyJ9.eyJpc3MiOiJodHRwczovL2Rldi04N2V2eDlydS5hdXRoMC5jb20vIiwic3ViIjoiYVc0Q2NhNzl4UmVMV1V6MGFFMkg2a0QwTzNjWEJWdENAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vZXhwZW5zZXMtYXBpIiwiaWF0IjoxNTcyMDA2OTU0LCJleHAiOjE1NzIwMDY5NjQsImF6cCI6ImFXNENjYTc5eFJlTFdVejBhRTJINmtEME8zY1hCVnRDIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.PUxE7xn52aTCohGiWoSdMBZGiYAHwE5FYie0Y1qUT68IHSTXwXVd6hn02HTah6epvHHVKA2FqcFZ4GGv5VTHEvYpeggiiZMgbxFrmTEY0csL6VNkX1eaJGcuehwQCRBKRLL3zKmA5IKGy5GeUnIbpPHLHDxr-GXvgFzsdsyWlVQvPX2xjeaQ217r2PtxDeqjlf66UYl6oY6AqNS8DH3iryCvIfCcybRZkc_hdy-6ZMoKT6Piijvk_aXdm7-QQqKJFHLuEqrVSOuBqqiNfVrG27QzAPuPOxvfXTVLXL2jek5meH6n-VWgrBdoMFH93QEszEDowDAEhQPHVs0xj7SIzA" url = "https://dev-87evx9ru.auth0.com/.well-known/jwks.json" optional_custom_headers = {"User-agent": "custom-user-agent"} jwks_client = PyJWKClient(url, headers=optional_custom_headers) signing_key = jwks_client.get_signing_key_from_jwt(token) jwt.decode( token, signing_key, audience="https://expenses-api", options={"verify_exp": False}, algorithms=["RS256"], ) ``` ```json {"iss": "https://dev-87evx9ru.auth0.com/", "sub": "aW4Cca79xReLWUz0aE2H6kD0O3cXBVtC@clients", "aud": "https://expenses-api", "iat": 1572006954, "exp": 1572006964, "azp": "aW4Cca79xReLWUz0aE2H6kD0O3cXBVtC", "gty": "client-credentials"} ``` -------------------------------- ### Suppress Insecure Key Length Warnings Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Uses the standard warnings module to ignore InsecureKeyLengthWarning. ```python import warnings import jwt warnings.filterwarnings("ignore", category=jwt.InsecureKeyLengthWarning) ``` -------------------------------- ### Decode JWT with Allowed Algorithms Source: https://github.com/jpadilla/pyjwt/blob/master/docs/algorithms.md Use the `algorithms` parameter in `jwt.decode()` to specify a list of permitted algorithms. The JWT's `alg` header must match one of these to be accepted. This prevents algorithm downgrade attacks. ```python jwt.decode(encoded, "secret", algorithms=["HS512", "HS256"]) ``` -------------------------------- ### Encode JWT with nbf claim Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Demonstrates encoding a JWT with an 'nbf' claim using either a numeric timestamp or a timezone-aware datetime object. ```pycon >>> token = jwt.encode({"nbf": 1371720939}, "secret") >>> token = jwt.encode({"nbf": datetime.datetime.now(tz=timezone.utc)}, "secret") ``` -------------------------------- ### Encode JWT with 'none' algorithm Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Demonstrates how to encode a JWT payload using the 'none' algorithm. This change was introduced to allow explicit use of the 'none' algorithm. ```pycon >>> import jwt >>> jwt.encode({"payload": "abc"}, key=None, algorithm="none") ``` -------------------------------- ### Decode JWT with 'none' algorithm Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Demonstrates how to decode a JWT payload using the 'none' algorithm. This change was introduced to allow explicit use of the 'none' algorithm. ```pycon >>> import jwt >>> jwt.decode(token, key=None, algorithms=["none"]) ``` -------------------------------- ### Encode and Decode with ES256 (ECDSA) Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Use ES256 for ECDSA encoding and decoding. Requires the 'cryptography' module. Ensure your private and public keys are correctly formatted. ```python >>> import jwt >>> private_key = b"-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIHAhM7P6HG3LgkDvgvfDeaMA6uELj+jEKWsSeOpS/SfYoAoGCCqGSM49\nAwEHoUQDQgAEXHVxB7s5SR7I9cWwry/JkECIRekaCwG3uOLCYbw5gVzn4dRmwMyY\nUJFcQWuFSfECRK+uQOOXD0YSEucBq0p5tA==\n-----END EC PRIVATE KEY-----\n" ``` ```python >>> public_key = b"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXHVxB7s5SR7I9cWwry/JkECIReka\nCwG3uOLCYbw5gVzn4dRmwMyYUJFcQWuFSfECRK+uQOOXD0YSEucBq0p5tA==\n-----END PUBLIC KEY-----\n" ``` ```python >>> encoded = jwt.encode({"some": "payload"}, private_key, algorithm="ES256") ``` ```python >>> jwt.decode(encoded, public_key, algorithms=["ES256"]) {'some': 'payload'} ``` -------------------------------- ### Decode JWT with signature verification disabled (v1.x syntax) Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst This shows the older v1.x syntax for decoding a JWT with signature verification disabled. It is recommended to use the newer 'options' dictionary for such configurations. ```python jwt.decode(jwt=token, key='secret', algorithms=['HS256'], options={"verify_signature": False}) ``` -------------------------------- ### Load Passphrase-Protected RSA Private Key Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md When your RSA private key is protected by a passphrase, use `cryptography.hazmat.primitives.serialization.load_pem_private_key` to load it. This allows you to then use the loaded key object for JWT encoding. ```python from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend pem_bytes = b"-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-128-CBC,C9C8F89EC68D15F26EB9B9695216C6DC\nE3lvX0dYjDxC0DIDitwNj+mEvU48Cqlp9esIeVmfcFmM6KpuQEA4asg/19kldbRq\ntOAYwmMuzz6GNYtX6sQXcStUE3pKMiMaTuP9WXzTc0boSYsGpGoQLtGv3h+0lkPu\nTGaktEhIfplAYlmsS/twr9Jh9QZjEs3dEMwpuF8A/iDZFeIE2thZL0bo38VWorgZ\nTCoOlC7qGtaeDvXXYrMvAUw3lN9A+DvxuPvbGqfqiHVBhxRcQEcR5p65lKP/V0WQ\nDe0AqCx1ghYGnExT7I4GLfr7Ux3F1UcVldPPsNeCTR/5YMOYDw7o5CZZ2TM39T33\nDBwfRhDqKe4bMUQcvcD54S2tfW7tEekm6mx5JwzW11sd0Gprj2uggDTOj3ce2yzM\nzl/dfbyFgh6v4jFeblIgvQ4VPg9nfCaRhatw5KXnfHBvmvdxlQ1Qp5P43ThXjI2a\njaJdm2lu1DLhf1OYGeQ0ytDDPzvhrZrdEJ8jbB3VCn4O/hvCtdsp7jVw2Djxmw2A\niRz2zlZJUlaytbi/DMpEVFwIzpuiDkpJ+ekzAsBbm/rGR/tjCEtHzVuoQNUWI93k\n0FML+Zzb6AkBWYjBXDZtzwJpMdNr8Vvh3krZySbRzQstqL2PYuNoSZ8/1xnnVqTV\nA0pDX7OS856AXQzQ1FRjjk/Jd0k6jGj8d7LzVgMnb8VknKvshlLmZDz8Sqa1coN4\n0Z1VfiT0Hzlk0fkoGtRjhSc3MB6ZLg7vVlY5vb4bRrTX79s/p8Y/OecYnGC6qhTi\n+VyJiMfwXyjFjIWYH8Y3G0QLkvOrTxLAY/3B2TU5wVSD7lfnPKOatMK1W0DHu5jp\nG9PPTzK9ol3v6Pk0prYg1fiApb6CCBUeZBvCIbJCzYrL/yBV/xYlCwAekLNGz9Vj\nNQUoiJqi27fOQi+ZXCrF7gYj8afo/xrg0tf7YqoOty8qfsozXzqwHKn+PcZOcqa5\n5rIqjLOO2f6KO2dxBeZK6zmzg7K/8RjvsNkEuXffec/nwnC10OVoMbE4wyPmNUQi\ndSuZ6xWBqiREjodLL+Ez/N1Qa52kuLSigrrSBTM2e42PWDV1sNW5V2wwlnolXFF6\n2Xp74WaGdnwF4Afrm7AnaBxdmfjk/a+c2uzPkZkpVnxrW3l8afphhKpRoTLzqDPp\nZGc5Fx9UZsmX18B8D1OGbf4aVLUkoqPPHbccCI+wByoAgIoq+y2391fP/Db6fY9A\nR4t2uuP2sNqDfYtzPYikePBXhYlldE1UHJ378g8pTiRHOI9BhuKIOIbVngPUYk4I\nwhYct2K84HjvR3iRnobK0UmmNOqtK0AtUqne+xaj1f3OwMZSvTUe7/jESgw1e1tn\nulKiWnKnmTSZkeTIp6itui2T7ewfNyitPtvnhoH1fBnMyUVACip0SLXp1fwQ7iCc\namPFFKo7p+C7P3l0ItegaMHywOSTBvK39DQTIpF9ml8VCQ+UyPOv/LnSJk1mbJN/\nc2Hdoj5dMa6T7ysIwZGEissJ/MEP+dpRs7VmCjWrHCDHfeAIO0n32g4zbzlNc/OA\nIdCXTvi4xUEn2n3JPt5Ba9qDUevaHSERlLxI+9a4ZaZeg4t+AzY0ur6+RWx+PaXB\n-----END RSA PRIVATE KEY----- ``` ```python passphrase = b"abc123" ``` ```python private_key = serialization.load_pem_private_key( pem_bytes, password=passphrase, backend=default_backend() ) ``` ```python encoded = jwt.encode({"some": "payload"}, private_key, algorithm="RS256") ``` -------------------------------- ### Encode and Decode with EdDSA (Ed25519) Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Use EdDSA for Ed25519 encoding and decoding. Requires the 'cryptography' module. Ensure your private and public keys are correctly formatted. ```python >>> import jwt >>> private_key = "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIPtUxyxlhjOWetjIYmc98dmB2GxpeaMPP64qBhZmG13r\n-----END PRIVATE KEY-----\n" ``` ```python >>> public_key = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA7p4c1IU6aA65FWn6YZ+Bya5dRbfd4P6d4a6H0u9+gCg= -----END PUBLIC KEY-----\n" ``` ```python >>> encoded = jwt.encode({"some": "payload"}, private_key, algorithm="EdDSA") ``` ```python >>> jwt.decode(encoded, public_key, algorithms=["EdDSA"]) {'some': 'payload'} ``` -------------------------------- ### Decode JWT with options to require specific claims Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Use this to ensure that specific claims (like 'exp') are present in the JWT payload. The 'require' option takes a list of claim names. ```python jwt.decode(encoded, key, algorithms=["HS256"], options={"require": ["exp"]}) ``` -------------------------------- ### Encode JWT with expiration time Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Set the 'exp' claim using either a UTC UNIX timestamp or a datetime object. ```pycon >>> from datetime import datetime, timezone >>> token = jwt.encode({"exp": 1371720939}, "secret") >>> token = jwt.encode({"exp": datetime.now(tz=timezone.utc)}, "secret") ``` -------------------------------- ### Extract keys from x509 certificate Source: https://github.com/jpadilla/pyjwt/blob/master/docs/faq.md Uses the cryptography library to parse a PEM-encoded certificate and retrieve its public or private key components. ```python from cryptography.x509 import load_pem_x509_certificate cert_str = b"-----BEGIN CERTIFICATE-----MIIDETCCAfm..." cert_obj = load_pem_x509_certificate(cert_str) public_key = cert_obj.public_key() private_key = cert_obj.private_key() ``` -------------------------------- ### Validate nbf claim with leeway Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Uses leeway to validate a token where the 'nbf' time is slightly in the future, accounting for clock skew. ```pycon >>> import time, datetime >>> from datetime import timezone >>> payload = { ... "nbf": datetime.datetime.now(tz=timezone.utc) - datetime.timedelta(seconds=3) ... } >>> token = jwt.encode(payload, "secret") >>> # JWT payload is not valid yet >>> # But with some leeway, it will still validate >>> decoded = jwt.decode(token, "secret", leeway=5, algorithms=["HS256"]) ``` -------------------------------- ### Decode JWT with explicit algorithms Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Requires specifying the allowed algorithms for decoding a JWT. This enhances security by preventing algorithm confusion attacks. ```python jwt.decode(encoded, key, algorithms=["HS256"]) ``` -------------------------------- ### Set and Retrieve JWT ID Claim Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Uses a UUID to generate a unique 'jti' claim for replay attack prevention. ```pycon >>> import uuid >>> payload = {"some": "payload", "jti": str(uuid.uuid4())} >>> token = jwt.encode(payload, "secret") >>> decoded = jwt.decode(token, "secret", algorithms=["HS256"]) >>> decoded["jti"] '3fa85f64-5717-4562-b3fc-2c963f66afa6' ``` -------------------------------- ### Decode JWT with options to disable expiration verification Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Use this when you need to decode a JWT but want to bypass the expiration check. Ensure you handle expiration logic manually if necessary. ```python jwt.decode(encoded, key, algorithms=["HS256"], options={"verify_exp": False}) ``` -------------------------------- ### Specify Additional Headers in JWT Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Add custom headers like 'kid' to a JWT during encoding. The 'typ' header is attached by default and can be explicitly set to None to omit it. ```python >>> jwt.encode( ... {"some": "payload"}, ... "secret", ... algorithm="HS256", ... headers={"kid": "230498151c214b788dd97f22b85410a5"}, ... ) 'eyJhbGciOiJIUzI1NiIsImtpZCI6IjIzMDQ5ODE1MWMyMTRiNzg4ZGQ5N2YyMmI4NTQxMGE1IiwidHlwIjoiSldUIn0.eyJzb21lIjoicGF5bG9hZCJ9.0n16c-shKKnw6gervyk1Dge35tvzbzQ_KCV3H3bgoJ0' ``` ```python >>> jwt.encode( ... {"some": "payload"}, ... "secret", ... algorithm="HS256", ... headers={"typ": None}, ... ) 'eyJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9...' ``` -------------------------------- ### Enforce Minimum Key Length Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Configures a PyJWT instance to raise an InvalidKeyError when keys are too short. ```pycon >>> strict_jwt = jwt.PyJWT(options={"enforce_minimum_key_length": True}) >>> try: ... strict_jwt.encode({"some": "payload"}, "short", algorithm="HS256") ... except jwt.InvalidKeyError: ... print("key too short") ... key too short ``` -------------------------------- ### Validate audience claim with array Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Validates a JWT containing an array of audience strings against a specific expected audience. ```pycon >>> payload = {"some": "payload", "aud": ["urn:foo", "urn:bar"]} >>> token = jwt.encode(payload, "secret") >>> decoded = jwt.decode(token, "secret", audience="urn:foo", algorithms=["HS256"]) >>> decoded = jwt.decode(token, "secret", audience="urn:bar", algorithms=["HS256"]) ``` -------------------------------- ### Validate multiple accepted audiences Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Allows passing an iterable to the audience parameter to accept multiple potential audience values. ```pycon >>> payload = {"some": "payload", "aud": "urn:foo"} >>> token = jwt.encode(payload, "secret") >>> decoded = jwt.decode( ... token, "secret", audience=["urn:foo", "urn:bar"], algorithms=["HS256"] ... ) >>> try: ... jwt.decode(token, "secret", audience=["urn:invalid"], algorithms=["HS256"]) ... except jwt.InvalidAudienceError: ... print("invalid audience") ... invalid audience ``` -------------------------------- ### Decode JWT without signature validation Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Use verify_signature=False to read claims without verifying the signature. This is insecure and should only be used when the token's integrity is not required. ```pycon >>> jwt.decode(encoded, options={"verify_signature": False}) {'some': 'payload'} ``` -------------------------------- ### Encode JWT with iat claim Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Encodes a JWT with the 'iat' claim using either a numeric timestamp or a datetime object. ```pycon >>> token = jwt.encode({"iat": 1371720939}, "secret") >>> token = jwt.encode({"iat": datetime.datetime.now(tz=timezone.utc)}, "secret") ``` -------------------------------- ### Require Specific Claims Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Validates that required claims are present during the decoding process, raising MissingRequiredClaimError if any are absent. ```pycon >>> token = jwt.encode({"sub": "1234567890", "iat": 1371720939}, "secret") >>> try: ... jwt.decode( ... token, ... "secret", ... options={"require": ["exp", "iss", "sub"]}, ... algorithms=["HS256"], ... ) ... except jwt.MissingRequiredClaimError as e: ... print(e) ... Token is missing the "exp" claim ``` -------------------------------- ### Validate issuer claim Source: https://github.com/jpadilla/pyjwt/blob/master/docs/usage.md Checks the 'iss' claim during decoding and raises jwt.InvalidIssuerError if the issuer does not match. ```pycon >>> payload = {"some": "payload", "iss": "urn:foo"} >>> token = jwt.encode(payload, "secret") >>> try: ... jwt.decode(token, "secret", issuer="urn:invalid", algorithms=["HS256"]) ... except jwt.InvalidIssuerError: ... print("invalid issuer") ... invalid issuer ``` -------------------------------- ### Decode JWT with options to disable signature verification Source: https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst Use this to decode a JWT without verifying its signature. This is generally not recommended for security-sensitive applications. ```python jwt.decode(encoded, key, options={"verify_signature": False}) ```