Middleware

This middleware protects endpoints using JWT tokens.


Setup

JWTMiddleware wraps an ASGI app, and ensures a valid token is passed in the header. Otherwise a 403 error is returned. If the token is valid, the corresponding user_id is added to the ASGI scope.

blacklist

Optionally, you can pass in a blacklist argument, which is a subclass of JWTBlacklist. The implementation of the in_blacklist method is up to the user - the data could come from a database, a file, a Python list, or anywhere else.

# An example blacklist.

BLACKLISTED_TOKENS = ['abc123', 'def456']


class MyBlacklist(JWTBlacklist):
    async def in_blacklist(self, token: str) -> bool:
        return token in BLACKLISTED_TOKENS


asgi_app = JWTMiddleware(
    my_endpoint,
    secret='mysecret123',
    blacklist=MyBlacklist()
)

Hint

Blacklists are important if you have tokens with a long expiry date.

allow_unauthenticated

By default, if the JWT token is invalid then the HTTP request is rejected. However, by setting allow_unauthenticated=True the request will be allowed to continue instead. The following will be added to the ASGI scope:

  • user_id, which is set to None

  • jwt_error, explaining why the token is invalid (see JWTError)

It is then up to the endpoints in your application to check whether user_id is None and then reject the request.

This is useful when the middleware is wrapping lots of endpoints, and you want more control over which ones are protected, or want to take additional actions when an error occurs before rejecting the request.


Source

JWTMiddleware

class piccolo_api.jwt_auth.middleware.JWTMiddleware(asgi: ASGIApp, secret: str, auth_table: Type[BaseUser] = BaseUser, blacklist: JWTBlacklist = JWTBlacklist(), allow_unauthenticated: bool = False)[source]

Protects ASGI endpoints - only allows access if a JWT token is present in the authorization HTTP header.

Parameters:
  • asgi – The ASGI app to protect.

  • secret – The secret used to decode the JWT token.

  • auth_table – The Piccolo table containing users - either BaseUser or a subclass.

  • blacklist – Any tokens in this list will be rejected.

  • allow_unauthenticated – By default the middleware rejects any requests with an invalid token.

JWTBlacklist

class piccolo_api.jwt_auth.middleware.JWTBlacklist[source]

Inherit from this class, and override in_blacklist(). Used in conjunction with JWTMiddleware. An example is StaticJWTBlacklist.

async in_blacklist(token: str) bool[source]

Checks whether the token is in the blacklist.

StaticJWTBlacklist

class piccolo_api.jwt_auth.middleware.StaticJWTBlacklist(blacklist: List[str])[source]

A simple implementation of JWTBlacklist, which rejects a token if it’s in the given list.

JWTError

class piccolo_api.jwt_auth.middleware.JWTError(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

This enum contains all of the possible errors which can be returned by JWTMiddleware. If allow_unauthenticated=True then these errors will be added to the ASGI scope instead under jwt_error.

token_expired = 'Token has expired'
token_invalid = 'Token is invalid'
token_not_found = 'Token not found'
token_revoked = 'Token revoked'
user_not_found = 'User not found'