Middleware

This middleware protects endpoints using session cookies.


Setup

The middleware wraps your ASGI app.

Here’s a Starlette example:

from starlette import Starlette
from starlette.middleware.authentication import AuthenticationMiddleware
from piccolo_api.session_auth.middleware import SessionsAuthBackend

my_asgi_app = Starlette()

app = AuthenticationMiddleware(
    my_asgi_app,
    backend=SessionsAuthBackend(),
)

Here’s a FastAPI example:

from fastapi import FastAPI
from starlette.middleware.authentication import AuthenticationMiddleware
from piccolo_api.session_auth.middleware import SessionsAuthBackend

my_asgi_app = FastAPI()

app = AuthenticationMiddleware(
    my_asgi_app,
    backend=SessionsAuthBackend(),
)

On each request, the middleware looks for a session token held in a cookie, and whether a corresponding user is found in the database. If so, a user object is added to the ASGI scope.


Accessing user

In Starlette you can access the user in your endpoint using request.user or request.scope['user'].

from starlette.requests import Request
from starlette.endpoints import HTTPEndpoint
from starlette.responses import JSONResponse

class PostsEndpoint(HTTPEndpoint):
    async def get(self, request: Request):
        piccolo_user = request.user.user
        posts = await Post.select().where(
            Post.author.id == piccolo_user.id
        ).run()
        return JSONResponse(posts)

In FastAPI, you can also access the user from the request scope, as follows:

from fastapi.requests import Request
from fastapi.responses import JSONResponse

@app.get('/posts/')
def get_posts(request: Request):
    piccolo_user = request.user.user
    posts = await Post.select().where(
        Post.author.id == piccolo_user.id
    ).run()
    return JSONResponse(posts)

excluded_paths

This works identically to token auth - see excluded_paths.


Source

SessionsAuthBackend

class piccolo_api.session_auth.middleware.SessionsAuthBackend(auth_table: Type[BaseUser] = PiccoloBaseUser, session_table: Type[SessionsBase] = SessionsBase, cookie_name: str = 'id', admin_only: bool = True, superuser_only: bool = False, active_only: bool = True, increase_expiry: timedelta | None = None, allow_unauthenticated: bool = False, excluded_paths: Sequence[str] | None = None)[source]

Authenticaion middleware which uses session cookies.

Parameters:
  • auth_table – The Piccolo table used for authenticating users. It defaults to BaseUser.

  • session_table – The Piccolo table used for storing sessions. If defaults to SessionsBase.

  • cookie_name – The name of the session cookie. Override this if it clashes with other cookies in your application.

  • admin_only – If True, users which aren’t admins will be rejected.

  • superuser_only – If True, users which aren’t superusers will be rejected.

  • active_only – If True, users which aren’t active will be rejected.

  • increase_expiry – If set, the session expiry will be increased by this amount on each request, if it’s close to expiry. This allows sessions to have a short expiry date, whilst also providing a good user experience.

  • allow_unauthenticated – If True, when a matching user session can’t be found, the request still continues, but an unauthenticated user is added to the scope. It’s then up to the application’s endpoints to check if a user is authenticated or not using request.user.is_authenticated. If False, the request is automatically rejected if a user session can’t be found.

  • excluded_paths – These paths don’t require a session cookie - useful if you want to exclude a few URLs, such as docs.