Skip to content

TokenPayload

Bases: BaseModel

JWT Payload base model

Parameters:

Name Type Description Default
jti Optional[str]

JWT unique identifier. Defaults to UUID4.

required
iss Optional[str]

JWT issuer. Defaults to None.

required
sub Optional[str]

JWT subject. Defaults to None.

required
aud Optional[str]

JWT audience. Defaults to None.

required
exp Numeric | DateTimeExpression | None

Expiry date claim. Defaults to None.

required
nbf Numeric | DateTimeExpression | None

Not before claim. Defaults to None.

required
iat Numeric | DateTimeExpression | None

Issued at claim. Defaults to None.

required
type Optional[str]

Token type. Default to None.

required
csrf Optional[str]

CSRF double submit token. Default to None.

required
scopes Optional[List[str]]

TODO.

required
fresh bool

Token freshness state. Defaults to False.

required
Source code in fastjwt/models.py
class TokenPayload(BaseModel):
    """JWT Payload base model

    Args:
        jti (Optional[str]): JWT unique identifier. Defaults to UUID4.
        iss (Optional[str]): JWT issuer. Defaults to None.
        sub (Optional[str]): JWT subject. Defaults to None.
        aud (Optional[str]): JWT audience. Defaults to None.
        exp (Numeric | DateTimeExpression | None): Expiry date claim. Defaults to None.
        nbf (Numeric | DateTimeExpression | None): Not before claim. Defaults to None.
        iat (Numeric | DateTimeExpression | None): Issued at claim. Defaults to None.
        type (Optional[str]): Token type. Default to None.
        csrf (Optional[str]): CSRF double submit token. Default to None.
        scopes (Optional[List[str]]): TODO.
        fresh (bool): Token freshness state. Defaults to False.
    """

    jti: Optional[str] = Field(default_factory=get_uuid)
    iss: Optional[str] = None
    sub: Optional[str] = None
    aud: Optional[str] = None
    exp: Optional[Union[Numeric, DateTimeExpression]] = None
    nbf: Optional[Union[Numeric, DateTimeExpression]] = None
    iat: Optional[Union[Numeric, DateTimeExpression]] = Field(
        default_factory=lambda: int(get_now_ts())
    )
    type: Optional[str] = None
    csrf: Optional[str] = None
    scopes: Optional[List[str]] = None
    fresh: bool = False

    class Config:
        extra = Extra.allow

    @property
    def _additional_fields(self) -> set[str]:
        return set(self.__dict__) - set(self.__fields__)

    @property
    def extra_dict(self):
        return self.dict(include=self._additional_fields)

    @property
    def issued_at(self) -> datetime.datetime:
        """Cast the 'iat' claim as a datetime.datetime

        Raises:
            TypeError: 'iat' claim is not of type float | int | datetime.datetime

        Returns:
            datetime.datetime: UTC Datetime token issued date
        """
        if isinstance(self.iat, (float, int)):
            return datetime.datetime.fromtimestamp(self.iat, tz=datetime.timezone.utc)
        elif isinstance(self.iat, datetime.datetime):
            return self.iat
        else:
            raise TypeError(
                "'iat' claim should be of type float | int | datetime.datetime"
            )

    @property
    def expiry_datetime(self) -> datetime.datetime:
        """Cast the 'exp' claim as a datetime.datetime

        Raises:
            TypeError: 'exp' claim is not of type float | int | datetime.datetime | datetime.timedelta

        Returns:
            datetime.datetime: UTC Datetime token expiry date
        """
        if isinstance(self.exp, datetime.datetime):
            return self.exp
        elif isinstance(self.exp, datetime.timedelta):
            return self.issued_at + self.exp
        elif isinstance(self.exp, (float, int)):
            return datetime.datetime.fromtimestamp(self.exp, tz=datetime.timezone.utc)
        else:
            raise TypeError(
                "'exp' claim should be of type float | int | datetime.datetime | datetime.timedelta"
            )

    @property
    def time_until_expiry(self) -> datetime.timedelta:
        """Return the time remaining until expiry

        Returns:
            datetime.timedelta: time remaining until expiry
        """
        return self.expiry_datetime - get_now()

    @property
    def time_since_issued(self) -> datetime.timedelta:
        """Return the time elapsed since token has been issued

        Returns:
            datetime.timedelta: time elapsed since token has been issued
        """
        return get_now() - self.issued_at

    @validator("exp", "nbf", always=True)
    def _set_default_ts(cls, value):
        if isinstance(value, datetime.datetime):
            return value.timestamp()
        elif isinstance(value, datetime.timedelta):
            return (get_now() + value).timestamp()
        return value

    def has_scopes(self, *scopes: Sequence[str]) -> bool:
        """Checks if a given scope is contained within TokenPayload scopes

        Args:
            *scopes (Sequence[str]): scopes to verify

        Returns:
            bool: Whether the scopes are contained in the payload scopes
        """
        return all([s in self.scopes for s in scopes])

    def encode(
        self,
        key: str,
        algorithm: str,
        ignore_errors: bool = True,
        headers: Optional[Dict[str, Any]] = None,
    ) -> str:
        """Encode the payload

        Args:
            key (str): Secret key to encode the payload
            algorithm (str): Algorithm to use to encode the payload
            ignore_errors (bool, optional): Ignore validation errors. Defaults to True.
            headers (Optional[Dict[str, Any]], optional): TODO. Defaults to None.

        Returns:
            str: encoded token
        """
        # TODO Handle Headers
        # TODO Handle Extra fields
        return create_token(
            key=key,
            algorithm=algorithm,
            uid=self.sub,
            jti=self.jti,
            issued=self.iat,
            type=self.type,
            expiry=self.exp,
            fresh=self.fresh,
            csrf=self.csrf,
            audience=self.aud,
            issuer=self.iss,
            not_before=self.nbf,
            ignore_errors=ignore_errors,
            headers=headers,
        )

    @classmethod
    def decode(
        cls,
        token: str,
        key: str,
        algorithms: Sequence[AlgorithmType] = ["HS256"],
        audience: Optional[StrOrSeq] = None,
        issuer: Optional[str] = None,
        verify: bool = True,
    ) -> "TokenPayload":
        """Given a token returns the associated JWT payload

        Args:
            token (str): Token to decode
            key (str): Secret to decode the token
            algorithms (Sequence[AlgorithmType], optional): Algorithms to use to decode the token. Defaults to ["HS256"].
            audience (Optional[StrOrSeq], optional): Audience to verify. Defaults to None.
            issuer (Optional[str], optional): Issuer to verify. Defaults to None.
            verify (bool, optional): Enable verification. Defaults to True.

        Returns:
            TokenPayload: The decoded JWT payload
        """
        payload = decode_token(
            token=token,
            key=key,
            algorithms=algorithms,
            audience=audience,
            issuer=issuer,
            verify=verify,
        )
        return cls.parse_obj(payload)

expiry_datetime: datetime.datetime property

Cast the 'exp' claim as a datetime.datetime

Raises:

Type Description
TypeError

'exp' claim is not of type float | int | datetime.datetime | datetime.timedelta

Returns:

Type Description
datetime

datetime.datetime: UTC Datetime token expiry date

issued_at: datetime.datetime property

Cast the 'iat' claim as a datetime.datetime

Raises:

Type Description
TypeError

'iat' claim is not of type float | int | datetime.datetime

Returns:

Type Description
datetime

datetime.datetime: UTC Datetime token issued date

time_since_issued: datetime.timedelta property

Return the time elapsed since token has been issued

Returns:

Type Description
timedelta

datetime.timedelta: time elapsed since token has been issued

time_until_expiry: datetime.timedelta property

Return the time remaining until expiry

Returns:

Type Description
timedelta

datetime.timedelta: time remaining until expiry

decode(token, key, algorithms=['HS256'], audience=None, issuer=None, verify=True) classmethod

Given a token returns the associated JWT payload

Parameters:

Name Type Description Default
token str

Token to decode

required
key str

Secret to decode the token

required
algorithms Sequence[AlgorithmType]

Algorithms to use to decode the token. Defaults to ["HS256"].

['HS256']
audience Optional[StrOrSeq]

Audience to verify. Defaults to None.

None
issuer Optional[str]

Issuer to verify. Defaults to None.

None
verify bool

Enable verification. Defaults to True.

True

Returns:

Name Type Description
TokenPayload TokenPayload

The decoded JWT payload

Source code in fastjwt/models.py
@classmethod
def decode(
    cls,
    token: str,
    key: str,
    algorithms: Sequence[AlgorithmType] = ["HS256"],
    audience: Optional[StrOrSeq] = None,
    issuer: Optional[str] = None,
    verify: bool = True,
) -> "TokenPayload":
    """Given a token returns the associated JWT payload

    Args:
        token (str): Token to decode
        key (str): Secret to decode the token
        algorithms (Sequence[AlgorithmType], optional): Algorithms to use to decode the token. Defaults to ["HS256"].
        audience (Optional[StrOrSeq], optional): Audience to verify. Defaults to None.
        issuer (Optional[str], optional): Issuer to verify. Defaults to None.
        verify (bool, optional): Enable verification. Defaults to True.

    Returns:
        TokenPayload: The decoded JWT payload
    """
    payload = decode_token(
        token=token,
        key=key,
        algorithms=algorithms,
        audience=audience,
        issuer=issuer,
        verify=verify,
    )
    return cls.parse_obj(payload)

encode(key, algorithm, ignore_errors=True, headers=None)

Encode the payload

Parameters:

Name Type Description Default
key str

Secret key to encode the payload

required
algorithm str

Algorithm to use to encode the payload

required
ignore_errors bool

Ignore validation errors. Defaults to True.

True
headers Optional[Dict[str, Any]]

TODO. Defaults to None.

None

Returns:

Name Type Description
str str

encoded token

Source code in fastjwt/models.py
def encode(
    self,
    key: str,
    algorithm: str,
    ignore_errors: bool = True,
    headers: Optional[Dict[str, Any]] = None,
) -> str:
    """Encode the payload

    Args:
        key (str): Secret key to encode the payload
        algorithm (str): Algorithm to use to encode the payload
        ignore_errors (bool, optional): Ignore validation errors. Defaults to True.
        headers (Optional[Dict[str, Any]], optional): TODO. Defaults to None.

    Returns:
        str: encoded token
    """
    # TODO Handle Headers
    # TODO Handle Extra fields
    return create_token(
        key=key,
        algorithm=algorithm,
        uid=self.sub,
        jti=self.jti,
        issued=self.iat,
        type=self.type,
        expiry=self.exp,
        fresh=self.fresh,
        csrf=self.csrf,
        audience=self.aud,
        issuer=self.iss,
        not_before=self.nbf,
        ignore_errors=ignore_errors,
        headers=headers,
    )

has_scopes(*scopes)

Checks if a given scope is contained within TokenPayload scopes

Parameters:

Name Type Description Default
*scopes Sequence[str]

scopes to verify

()

Returns:

Name Type Description
bool bool

Whether the scopes are contained in the payload scopes

Source code in fastjwt/models.py
def has_scopes(self, *scopes: Sequence[str]) -> bool:
    """Checks if a given scope is contained within TokenPayload scopes

    Args:
        *scopes (Sequence[str]): scopes to verify

    Returns:
        bool: Whether the scopes are contained in the payload scopes
    """
    return all([s in self.scopes for s in scopes])