Skip to content

JWT Utitilies

Missil uses the excellent Python-jose as backend to offer some JWT conveniences.

Encode JWT Token

Usage Example

from datetime import datetime
from missil import encode_jwt_token

SECRET_KEY = "averysecretkey"

base_date = datetime(2094, 2, 26)
claims = {"name": "John Doe", "userPrivileges": {"finances": 1}}
token = encode_jwt_token(claims, SECRET_KEY, 8, base=base_date)

print(token)

API Reference

missil.encode_jwt_token

encode_jwt_token(claims, secret, exp, base=None, algorithm='HS256')

Create a JWT token.

PARAMETER DESCRIPTION
claims

Token user data.

TYPE: dict[str, Any]

secret

Secret key to sign the token.

TYPE: str

exp

Token expiration in hours.

TYPE: int

base

Token expiration base datetime, where the final datetime is given by base + exp, by default datetime.now(timezone.utc)

TYPE: datetime DEFAULT: None

algorithm

Encode algorithm, by default "HS256"

TYPE: str DEFAULT: 'HS256'

RETURNS DESCRIPTION
str

description

Source code in missil/jwt_utilities.py
def encode_jwt_token(
    claims: dict[str, Any],
    secret: str,
    exp: int,
    base: datetime | None = None,
    algorithm: str = "HS256",
) -> str:
    """
    Create a JWT token.

    Parameters
    ----------
    claims : dict[str, Any]
        Token user data.
    secret : str
        Secret key to sign the token.
    exp : int, optional
        Token expiration in hours.
    base : datetime, optional
        Token expiration base datetime, where the final datetime is given by
        base + exp, by default datetime.now(timezone.utc)
    algorithm : str, optional
        Encode algorithm, by default "HS256"

    Returns
    -------
    str
        _description_
    """
    if base is None:
        base = datetime.now(timezone.utc)

    to_encode = claims.copy()
    to_encode.update({"exp": base + timedelta(exp)})
    return jwt.encode(to_encode, key=secret, algorithm=algorithm)

Decode JWT Token

Usage Example

from missil import decode_jwt_token

TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJ1c2VyUHJpdmlsZWdlcyI6eyJmaW5hbmNlcyI6MX0sImV4cCI6MzkxODY3MjAwMH0.BWkskBJZj68mLaxqgdO0occL_FY8RSdEnqNSC6Swxh0"
SECRET_KEY = "averysecretkey"
decoded_token = decode_jwt_token(TOKEN, SECRET_KEY)

print(decoded_token)  # {'name': 'John Doe', 'userPrivileges': {'finances': 1}, 'exp': 3918672000}

API Reference

missil.decode_jwt_token

decode_jwt_token(token, secret_key, algorithm='HS256')

Decode a JWT Token using Python-jose.

PARAMETER DESCRIPTION
token

Token to be decoded.

TYPE: str

secret_key

Secret key to decode the signed token.

TYPE: str

algorithm

Decoding algoritgm. See Python-jose docs for more details.

TYPE: str DEFAULT: 'HS256'

RETURNS DESCRIPTION
dict[str, Any]

Decoded claims.

RAISES DESCRIPTION
TokenErrorException

The token signature has expired.

TokenErrorException

The token claim is invalid.

TokenErrorException

Generalist exception. The token signature is invalid.

TokenErrorException

Most generalist exception. The token is invalid.

Source code in missil/jwt_utilities.py
def decode_jwt_token(
    token: str, secret_key: str, algorithm: str = "HS256"
) -> dict[str, Any]:
    """
    Decode a JWT Token using Python-jose.

    Parameters
    ----------
    token : str
        Token to be decoded.
    secret_key : str
        Secret key to decode the signed token.
    algorithm : str
        Decoding algoritgm. See Python-jose docs for more details.

    Returns
    -------
    dict[str, Any]
        Decoded claims.

    Raises
    ------
    TokenErrorException
        The token signature has expired.
    TokenErrorException
        The token claim is invalid.
    TokenErrorException
        Generalist exception. The token signature is invalid.
    TokenErrorException
        Most generalist exception. The token is invalid.
    """
    try:
        decoded_token = jwt.decode(token, secret_key, algorithms=algorithm)
    except ExpiredSignatureError as ese:
        raise TokenErrorException(
            status.HTTP_403_FORBIDDEN, "The token signature has expired."
        ) from ese
    except JWTClaimsError as jce:
        raise TokenErrorException(
            status.HTTP_403_FORBIDDEN, "The token claim is invalid."
        ) from jce
    except JWTError as je:  # generalist exception handler
        raise TokenErrorException(
            status.HTTP_403_FORBIDDEN, "The token signature is invalid."
        ) from je

    return decoded_token