Generate and parse JWT token with python

Install dependency

pip install authlib

We utilize authlib to handle JWT related stuff.

Prepare RSA public key and private key

Before playing with JWT, you should generate public key and private key first.

Please refer to Generate RSA public key and private key with python.

Code example

import time

from authlib.jose import jwt
from authlib.jose.errors import ExpiredTokenError

# token will expire in a week
TOKEN_TIMEOUT = 7 * 24 * 3600
# replace with YOUR OWN private key !!!
PRIVATE_KEY = '''
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEApjlvc9QrmaNWye9a95qZh0FiI7zz2d89QIw145XcU0/eJFIt
29Zvza57LIydsFLMvWWPmHrje1631QC3YJA5xl3UMBIOJQJHwvMIdQHEl2LToo6d
2sTfh+jNkgnsb9pQyVigje3L3mKHVTLacJYkUkCvBqK9n9HryIMMNj8/KWRNCbrI
sWOonicR0JzrdDafwbD2/H1qmsrzz/gOZFT+IjjItf6KFHdYuuWlgElwrM7AFhHz
vzQp8nw1L1ZVSpa5CGjMVCPJ+ri/HuF0U/JXWHkKY1+uZ1SyHoJ1XdnaxnZYNE+B
fWrnBRdRNCDkj6kpy/ofcf/fHWHROGmjt2P3SQIDAQABAoIBAB7L2VhOYN2QI446
KFJjdDpY5MPWSB9/equwznMh2rYcv/1etFxceE5VG0D/tF9sl74nSNlpOygqPkja
Xx8m2W1lCOD3F2PH7l+yA0kaUL/zcV5WqexUOU3G1f9Ok12NxxXms6hX/ENxYb1p
NItTZdtPXJ4QHK21iMeXb/XE9gDG5XJrnDOxpe8aETns8J4Z4DItH8SDYxEL2OHM
UWdwBIXAxhWV17sNl8MCevzeH37DhiFkEI4777GT/8UpQ6unbY/9pIFI3UdoK6y/
VeKt8+ST6sK3SheUEtzsOWeyUf5ZCMPxbbnVRBG2xoPxJZpJ90CALPzDgoSx9CKR
kdSPCOECgYEAtmL65wuSqtu+0i/EAECFocqu8OlC9YJACRm+yq9P7TNlYKTMp27h
nsIVhGXm6dvqjCr/zxRcTFPzXfI1HdOtQ6Qk9Lq/9q3DRQYTRi2K4v2HqL+i9sFu
b7Tjysn9kGJEApzQTkXcdz2XjmIVbcVPOvsnS3gXWBS2XC2RQsTd830CgYEA6VB+
jPKQkR6gvw8njM8G1tUI+4p0RzVS62+m4Ach6ODiFZRhS9YXiycxPdU/pXQERgfz
nW3miqS9WnCt1A5QHHjm2hwUtPnxPMQG7LSY0h//GY/Kcm69mbiI5qBDez/pJmKy
55VxYpoxc2dTU82beJwgQjmSLuYqqNr9uxliRL0CgYEAjh4EeiKHb8F5KJj1tmiQ
eGjR9oEcnueWdEDubUs8EY3Z8fuYSONaxXVghOFOlG27jus2l6q63PMRkOPZxdsa
iLmP3m7ihBoULWW1gRqdvZBms/RXzMUfA8ZFNdA9V9NqQUrl+gfv6a5BuT3uirGT
slbf4Ku8LPM+wgbzyL5UYJUCgYEA2wgTVhTd/S7or5T1hy5P+F0UyriHQtZfmuE9
ozFu9yYveRzMXpqFjcBkbO0GjDgnTutmHBQxi1Tu4rnHpr0tHh2uc3JLSj8e5vIM
oilFEnaxUPj5kIY//tELzJ8F2u373mpoFBrq0Ct7YyDMTG9IlmjTq/hKMTcpM04r
R3ukEm0CgYBtI631qDKuYKJmvTKZTjaFxuJe4g46SKstBTktzn4Dikwu/3Z4gj7B
CRjqCqbXDnEuyfal69xiXKRe6oRFt2EACt75FuhCLLmpCcZQUy42lI7C5LzQCwn7
cz//erGKj/JusVValjfS9/fPTJukIlqvcGB/g3uZddDBzioSLBy8yQ==
-----END RSA PRIVATE KEY-----
'''

# replace with YOUR OWN public key !!!
PUBLIC_KEY = '''
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApjlvc9QrmaNWye9a95qZ
h0FiI7zz2d89QIw145XcU0/eJFIt29Zvza57LIydsFLMvWWPmHrje1631QC3YJA5
xl3UMBIOJQJHwvMIdQHEl2LToo6d2sTfh+jNkgnsb9pQyVigje3L3mKHVTLacJYk
UkCvBqK9n9HryIMMNj8/KWRNCbrIsWOonicR0JzrdDafwbD2/H1qmsrzz/gOZFT+
IjjItf6KFHdYuuWlgElwrM7AFhHzvzQp8nw1L1ZVSpa5CGjMVCPJ+ri/HuF0U/JX
WHkKY1+uZ1SyHoJ1XdnaxnZYNE+BfWrnBRdRNCDkj6kpy/ofcf/fHWHROGmjt2P3
SQIDAQAB
-----END PUBLIC KEY-----
'''


# store user_id in the generated token
def generate_token(user_id):
    header = {'alg': 'RS256'}
    payload = {
        'user_id': user_id,
        'exp': int(time.time() + TOKEN_TIMEOUT)
    }
    token = jwt.encode(header, payload, PRIVATE_KEY)
    token = token.decode()
    return token


# extract user_id from the token
def parse_token(token):
    claims = jwt.decode(token, PUBLIC_KEY)
    claims.validate()  # this line may raise ExpiredTokenError
    return claims['user_id']


# suppose the user_id is 12345
token = generate_token(12345)
print('JWT token:')
print(token)

try:
    user_id = parse_token(token)
    print('parse user_id from token:')
    print(user_id)
# handle possible exception raised by claims.validate() in parse_token function
except ExpiredTokenError:
    print('token expired')

Output example:

JWT token:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjM0NSwiZXhwIjoxNjU1OTYzMTY0fQ.drR9gujZnKKrhpX8E1uwS0vv3oC6YZlyJDJBz4XgRryFBC4ueJ7wDEleuwgFM1jRmoY-aB8qn113xohzi56h9HR2lFwfKUzvHVbKHpplJJIHGWnnSLz_PVmUk4EkbuM7j9ziS9pJBaUET3tWWiIruUIYj3OFNfEWiUUbkPbyQnvN8wcJSKuzdQGg72yhdezlHD8eT2klln07POOma_FNeXRztBiRmA5aFf7RYvS7dp_ljsd-2DiI4CDzxqQpn0PwXe93ciE_G9Lm265t9rGhMWAuYUtwxUTVTdpSZn14XCa_RvNPEMcQ46qliWv0bVGIUv0X-Y1f-8P27Ha3PyaeAw
parse user_id from token:
12345

It's worth noting that:

  • Tweak constant TOKEN_TIMEOUT as you wish.
  • Make sure that you replace constants PRIVATE_KEY and PUBLIC_KEY.
  • In the example, we stored user_id. You can store any stuff that is json serializable.
  • Do not omit to handle ExpiredTokenError in case the token is expired.
Posted on 2022-06-16