Skip to content

Transports

litestar_auth.authentication.transport

Move credentials between client and server (Bearer header vs HTTP-only cookies).

Transports are composed with a :class:~litestar_auth.authentication.strategy.Strategy inside an :class:~litestar_auth.authentication.backend.AuthenticationBackend.

BearerTransport

Bases: Transport

Transport that reads tokens from the Authorization header.

read_token(connection) async

Return the bearer token from the Authorization header when present.

Source code in litestar_auth/authentication/transport/bearer.py
@override
async def read_token(self, connection: ASGIConnection[Any, Any, Any, Any]) -> str | None:
    """Return the bearer token from the Authorization header when present."""
    authorization = connection.headers.get("Authorization")
    if authorization is None:
        return None

    scheme, _, token = authorization.partition(" ")
    if scheme.lower() != self.scheme:
        return None
    token = token.strip()
    if not token:
        return None
    return token

set_login_token(response, token)

Store the issued bearer token in the response body.

Returns:

Type Description
Response[Any]

The mutated response.

Source code in litestar_auth/authentication/transport/bearer.py
@override
def set_login_token(self, response: Response[Any], token: str) -> Response[Any]:
    """Store the issued bearer token in the response body.

    Returns:
        The mutated response.
    """
    response.content = {"access_token": token, "token_type": self.scheme}
    response.media_type = MediaType.JSON
    return response

set_logout(response)

Clear the response body because bearer transport keeps no client state.

Returns:

Type Description
Response[Any]

The mutated response.

Source code in litestar_auth/authentication/transport/bearer.py
@override
def set_logout(self, response: Response[Any]) -> Response[Any]:
    """Clear the response body because bearer transport keeps no client state.

    Returns:
        The mutated response.
    """
    response.content = None
    return response

CookieTransport(*, cookie_name='litestar_auth', max_age=None, path='/', domain=None, secure=True, httponly=True, samesite='lax', allow_insecure_cookie_auth=False, refresh_max_age=None)

Bases: Transport

Transport that stores authentication tokens in HTTP cookies.

Initialize the cookie transport configuration.

Parameters:

Name Type Description Default
cookie_name str

Name of the auth cookie.

'litestar_auth'
max_age int | None

Optional cookie max-age in seconds.

None
path str

Cookie path.

'/'
domain str | None

Optional cookie domain.

None
secure bool

Whether to set the Secure attribute.

True
httponly bool

Whether to set the HttpOnly attribute on the auth cookie.

True
samesite SameSitePolicy

SameSite policy for cookies.

'lax'
allow_insecure_cookie_auth bool

When True, allow cookie auth with plugin-managed CSRF disabled outside testing mode. This is unsafe for browser authentication and should only be used for controlled, non-browser scenarios.

False
refresh_max_age int | None

Optional cookie max-age in seconds for the refresh-token cookie. When None, falls back to max_age. Set this to match your strategy's refresh_max_age so the cookie outlives the access-token cookie.

None

Raises:

Type Description
ValueError

If samesite="none" is configured with secure=False.

Source code in litestar_auth/authentication/transport/cookie.py
def __init__(  # noqa: PLR0913
    self,
    *,
    cookie_name: str = "litestar_auth",
    max_age: int | None = None,
    path: str = "/",
    domain: str | None = None,
    secure: bool = True,
    httponly: bool = True,
    samesite: SameSitePolicy = "lax",
    allow_insecure_cookie_auth: bool = False,
    refresh_max_age: int | None = None,
) -> None:
    """Initialize the cookie transport configuration.

    Args:
        cookie_name: Name of the auth cookie.
        max_age: Optional cookie max-age in seconds.
        path: Cookie path.
        domain: Optional cookie domain.
        secure: Whether to set the Secure attribute.
        httponly: Whether to set the HttpOnly attribute on the auth cookie.
        samesite: SameSite policy for cookies.
        allow_insecure_cookie_auth: When ``True``, allow cookie auth with
            plugin-managed CSRF disabled outside testing mode. This is unsafe for
            browser authentication and should only be used for controlled,
            non-browser scenarios.
        refresh_max_age: Optional cookie max-age in seconds for the refresh-token
            cookie. When ``None``, falls back to ``max_age``. Set this to match
            your strategy's ``refresh_max_age`` so the cookie outlives the
            access-token cookie.

    Raises:
        ValueError: If ``samesite="none"`` is configured with ``secure=False``.
    """
    if samesite == "none" and not secure:
        msg = 'CookieTransport with samesite="none" requires secure=True.'
        raise ValueError(msg)
    self.cookie_name = cookie_name
    self.max_age = max_age
    self.path = path
    self.domain = domain
    self.secure = secure
    self.httponly = httponly
    self.samesite = samesite
    self.allow_insecure_cookie_auth = allow_insecure_cookie_auth
    # Security: separate refresh cookie lifetime prevents premature browser
    # deletion when access-token max_age is shorter than the refresh strategy TTL.
    self.refresh_max_age = refresh_max_age

Return the cookie key used to carry refresh tokens in cookie flows.

clear_refresh_token(response)

Expire the refresh-token cookie immediately.

Returns:

Type Description
Response[Any]

The mutated response.

Source code in litestar_auth/authentication/transport/cookie.py
def clear_refresh_token(self, response: Response[Any]) -> Response[Any]:
    """Expire the refresh-token cookie immediately.

    Returns:
        The mutated response.
    """
    return self._set_cookie(
        response,
        key=self.refresh_cookie_name,
        value="",
        max_age=0,
        httponly=True,
    )

read_logout_token(connection) async

Return the access-token cookie value to invalidate during logout.

Logout token sourcing is explicit here: cookie logout invalidates the access-token cookie and does not read refresh-token cookies.

Source code in litestar_auth/authentication/transport/cookie.py
async def read_logout_token(self, connection: ASGIConnection[Any, Any, Any, Any]) -> str | None:
    """Return the access-token cookie value to invalidate during logout.

    Logout token sourcing is explicit here: cookie logout invalidates the
    access-token cookie and does not read refresh-token cookies.
    """
    return await self.read_token(connection)

read_token(connection) async

Return the authentication token from the configured cookie.

Source code in litestar_auth/authentication/transport/cookie.py
@override
async def read_token(self, connection: ASGIConnection[Any, Any, Any, Any]) -> str | None:
    """Return the authentication token from the configured cookie."""
    return connection.cookies.get(self.cookie_name)

set_login_token(response, token)

Persist the issued token in the configured cookie.

Security

When this transport is used for browser-based authentication, you MUST pair it with an explicit CSRF protection mechanism (for example, a separate CSRF cookie and a required X-CSRF-Token header on state-changing requests). This is especially important when samesite=\"none\" is used for cross-site scenarios, because browsers will attach cookies automatically to cross-origin requests.

Returns:

Type Description
Response[Any]

The mutated response.

Source code in litestar_auth/authentication/transport/cookie.py
@override
def set_login_token(self, response: Response[Any], token: str) -> Response[Any]:
    r"""Persist the issued token in the configured cookie.

    Security:
        When this transport is used for browser-based authentication, you MUST
        pair it with an explicit CSRF protection mechanism (for example, a
        separate CSRF cookie and a required X-CSRF-Token header on state-changing
        requests). This is especially important when ``samesite=\"none\"`` is used
        for cross-site scenarios, because browsers will attach cookies
        automatically to cross-origin requests.

    Returns:
        The mutated response.
    """
    return self._set_cookie(
        response,
        key=self.cookie_name,
        value=token,
        max_age=self.max_age,
        httponly=self.httponly,
    )

set_logout(response)

Remove the access-token cookie by expiring it immediately.

Note

This transport-level method clears only the access-token cookie. The refresh-token cookie is cleared by :meth:AuthenticationBackend.logout, which calls :meth:clear_refresh_token after this method.

Returns:

Type Description
Response[Any]

The mutated response.

Source code in litestar_auth/authentication/transport/cookie.py
@override
def set_logout(self, response: Response[Any]) -> Response[Any]:
    """Remove the access-token cookie by expiring it immediately.

    Note:
        This transport-level method clears only the access-token cookie.
        The refresh-token cookie is cleared by
        :meth:`AuthenticationBackend.logout`, which calls
        :meth:`clear_refresh_token` after this method.

    Returns:
        The mutated response.
    """
    return self._set_cookie(
        response,
        key=self.cookie_name,
        value="",
        max_age=0,
        httponly=self.httponly,
    )

set_refresh_token(response, refresh_token)

Persist a refresh token in a dedicated HttpOnly cookie.

Note

This library intentionally treats refresh tokens as a separate artifact from the access-token cookie used for request authentication.

Returns:

Type Description
Response[Any]

The mutated response.

Source code in litestar_auth/authentication/transport/cookie.py
def set_refresh_token(self, response: Response[Any], refresh_token: str) -> Response[Any]:
    """Persist a refresh token in a dedicated HttpOnly cookie.

    Note:
        This library intentionally treats refresh tokens as a separate artifact from the
        access-token cookie used for request authentication.

    Returns:
        The mutated response.
    """
    # Security: use dedicated refresh_max_age so the cookie outlives the access-token cookie.
    effective_max_age = self.refresh_max_age if self.refresh_max_age is not None else self.max_age
    return self._set_cookie(
        response,
        key=self.refresh_cookie_name,
        value=refresh_token,
        max_age=effective_max_age,
        httponly=True,
    )

Transport

Bases: ABC

Abstract base class for moving auth tokens through HTTP requests.

read_token(connection) abstractmethod async

Extract an authentication token from the incoming connection.

Source code in litestar_auth/authentication/transport/base.py
@abstractmethod
async def read_token(self, connection: ASGIConnection[Any, Any, Any, Any]) -> str | None:
    """Extract an authentication token from the incoming connection."""

set_login_token(response, token) abstractmethod

Attach an authentication token to the login response.

Source code in litestar_auth/authentication/transport/base.py
@abstractmethod
def set_login_token(self, response: Response[Any], token: str) -> Response[Any]:
    """Attach an authentication token to the login response."""

set_logout(response) abstractmethod

Clear any transport-managed authentication state on logout.

Source code in litestar_auth/authentication/transport/base.py
@abstractmethod
def set_logout(self, response: Response[Any]) -> Response[Any]:
    """Clear any transport-managed authentication state on logout."""