middleware.csrf

Page actions AI-ready formats and sharing
Open LLM text
Share with AI
Ask Claude Ask ChatGPT Ask Gemini Ask Copilot

CSRF protection middleware — token-based, session-backed.

Generates a random token per session, validates it on state-changing requests (POST, PUT, PATCH, DELETE). Rejects with 403 if the token is missing or invalid.

Requires …

CSRF protection middleware — token-based, session-backed.

Generates a random token per session, validates it on state-changing requests (POST, PUT, PATCH, DELETE). Rejects with 403 if the token is missing or invalid.

RequiresSessionMiddleware— the CSRF token is stored in the session.

Usage::

from chirp.middleware.csrf import CSRFConfig, CSRFMiddleware
from chirp.middleware.sessions import SessionConfig, SessionMiddleware

app.add_middleware(SessionMiddleware(SessionConfig(secret_key="...")))
app.add_middleware(CSRFMiddleware(CSRFConfig()))

Templates::

<form method="post">
    {{ csrf_field() }}
    ...
</form>

htmx (via meta tag)::

<meta name="csrf-token" content="{{ csrf_token() }}">

For streamed or deferred responses (for exampleStream, TemplateStream, Suspense, or EventStream), capture the token in the handler and pass the raw value into template context instead of callingcsrf_token()during stream rendering.

middleware.csrf

Name Type Default Description
type
qualified_name
element_type
description
source_file
line_number
is_autodoc
autodoc_element
_autodoc_template
_autodoc_url_path
_autodoc_page_type
title
doc_content_hash

Symbols on this page

_set_stream_csrf
function
def _set_stream_csrf(token: str, field_name: str | None = None) -> tuple[Token[str | None], Token[str] | None]

Re-establish CSRF ContextVars while a streaming generator drains.

Parameters

Name Type Default Description
token str
field_name str | None None
get_csrf_token
function
def get_csrf_token() -> str

Return the current CSRF token.

RaisesLookupErrorif called outside a request with CSRFMiddlewareactive.

ForStream, Suspense, and EventStreamrenders, Chirp now re-establishes the connect-time token automatically for the drain, so get_csrf_token()works inside deferred blocks and SSE generators. The token is pinned at connect time for the life of an SSE connection. (You may still capture the token in the handler and pass it as plain template context if you prefer an explicit value.)

No parameters.

csrf_field
function
def csrf_field() -> str

Render a hidden input field with the CSRF token.

For use as a template global::

<form method="post">
    {{ csrf_field() }}
    ...
</form>

Renders a hidden<input> using the active CSRFConfig.field_name and the current request token.

No parameters.

csrf_token
function
def csrf_token() -> str

Return the raw CSRF token string.

For use as a template global in meta tags::

<meta name="csrf-token" content="{{ csrf_token() }}">

For streamed or deferred rendering, capture the token in the handler and pass it as plain template context instead.

No parameters.

CSRFConfig
class

CSRF middleware configuration.

CSRFMiddleware
class

Token-based CSRF protection middleware.

On every request:

  1. Loads or generates a CSRF token in the session.
  2. Makes the token available viaget_csrf_token()and template globals.
  3. On unsafe methods (POST, PUT, PATCH, DELETE), validates the token from either the form body or the request header.
  4. Rejects with 403 if the token is missing or invalid.

RequiresSessionMiddlewareto be registered first.

_validate_token
function async
async def _validate_token(request: Request, expected: str, config: CSRFConfig) -> None

Check the CSRF token from form data or header.

RaisesHTTPError(403)if the token is missing or invalid.

Parameters

Name Type Default Description
request Request
expected str
config CSRFConfig

View source · /home/runner/work/chirp/chirp/site/../src/chirp/middleware/csrf.py:1