API reference

This page documents the public API of aiohttp-client-middlewares.

Digest authentication

class aiohttp_client_middlewares.DigestAuthMiddleware(login, password, preemptive=True)[source]

HTTP digest authentication client middleware.

Parameters:
  • login (str) – login

  • password (str) – password

  • preemptive (bool) – Enable preemptive authentication (default: True)

This middleware implements HTTP Digest Authentication according to RFC 7616. It supports both auth and auth-int quality of protection (qop) modes and a variety of hashing algorithms (MD5, SHA, SHA-256, SHA-512 and their session variants).

It automatically handles the digest authentication handshake by:

  • Parsing 401 Unauthorized responses with WWW-Authenticate: Digest headers.

  • Generating the appropriate Authorization: Digest header on retry.

  • Maintaining nonce counts and challenge data per request.

  • Reusing authentication credentials for subsequent requests to the same protection space when preemptive=True (following RFC 7616 Section 3.6).

Preemptive authentication

By default (preemptive=True) the middleware remembers successful authentication challenges and automatically includes the Authorization header in subsequent requests to the same protection space. This avoids an extra round trip and matches how modern web browsers handle digest authentication.

If the server rejects the nonce as expired (a second 401, typically with stale=true), the middleware reissues the request once using the refreshed challenge.

To disable preemptive authentication and require a 401 challenge for every request, set preemptive=False:

# Default behavior - preemptive auth enabled
digest = DigestAuthMiddleware(login="user", password="pass")

# Disable preemptive auth - always wait for the 401 challenge
digest = DigestAuthMiddleware(login="user", password="pass", preemptive=False)

Origin scoping

The credentials are scoped to the origin of the first request the middleware handles. A request to a different origin is passed through untouched, so it never receives a digest response computed from those credentials, unless that origin falls within a protection space the anchor origin advertised through the RFC 7616 domain directive. Make the first request through the middleware against the intended origin, as the anchor is pinned to it and not reset for the life of the instance.

Usage

from aiohttp import ClientSession
from aiohttp_client_middlewares import DigestAuthMiddleware

digest = DigestAuthMiddleware(login="user", password="pass")
async with ClientSession(middlewares=(digest,)) as session:
    # The middleware automatically handles the digest auth handshake.
    async with session.get("http://protected.example.com") as resp:
        assert resp.status == 200