Expiring Tokens#

Note

This functionality is introduced in version 0.3.0.

JWTs should not be long-lived. This prevents the misuse of them by bad actors.

One method to do that is to use the "exp" claim defined in the JSON Web Token standard.

The “problem” with using the "exp" claim is that it is in the format of a NumericDate which is defined as the following:

A JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time, ignoring leap seconds. This is equivalent to the IEEE Std 1003.1, 2013 Edition [POSIX.1] definition “Seconds Since the Epoch”, in which each day is accounted for by exactly 86400 seconds, other than that non-integer values can be represented. See RFC 3339 for details regarding date/times in general and UTC in particular.

That’s no fun to calculate. Therefore, the jwtdown-fastapi library does that for you.

Setting the default expiration#

Since version 0.3.0, the Authenticator will set the expiration time for a JWT one hour after it is created. You can change the default expiration duration by passing in a timedelta when you create the Authenticator.

Let’s say that you wanted the JWT to expire in two hours rather than one. You would create a new timedelta for two hours, then pass that into the initialization of the Authenticator object.

# authenticator.py
import os
from datetime import timedelta
from jwtdown_fastapi.authentication import Authenticator


class MyAuthenticator(Authenticator):
    # Your implementation of Authenticator


two_hours = timedelta(hours=2)


authenticator = MyAuthenticator(
  os.environ["SIGNING_KEY"],
  exp=two_hours,
)

Expiration per JWT#

In some use cases, you may want to set the expiration for a JWT on a per-JWT basis. You can do that by overriding the Authenticator.get_exp method.

The following code checks to see if an account has the admin role and, if so, will set the expiration at 15 minutes to prevent misuse of the token.

# authenticator.py
import os
from datetime import timedelta
from jwtdown_fastapi.authentication import Authenticator
from pydantic import BaseModel


class MyAuthenticator(Authenticator):
    # Your implementation of Authenticator

    def get_exp(
        self,
        proposed: timedelta,
        account: Optional[Union[BaseModel, dict]],
    ) -> timedelta:
        if "admin" in account.roles:
            return timedelta(minutes=15)
        return proposed


authenticator = MyAuthenticator(os.environ["SIGNING_KEY"])