Skip to content

Basic Auth Guard

basic_auth(*, verify, realm) — HTTP Basic authentication (RFC 7617).

Signature

def basic_auth(
    *,
    verify: Callable[[str, str], AuthUser | None],
    realm: str = "lauren",
) -> type:
    ...

Parameters:

Parameter Type Default Description
verify callable Sync or async (username, password) -> AuthUser \| None. Return an AuthUser to allow, None to reject.
realm str "lauren" Realm used by basic_auth_challenge_handler for WWW-Authenticate.

Usage

from lauren import LaurenFactory, controller, get, module, use_guards
from lauren_guards import basic_auth, AuthUser

USERS = {"admin": "secret", "alice": "hunter2"}

def verify(username: str, password: str) -> AuthUser | None:
    if USERS.get(username) == password:
        return AuthUser(id=username, roles=("user",))
    return None

BasicGuard = basic_auth(verify=verify, realm="Admin Area")

@use_guards(BasicGuard)
@controller("/admin")
class AdminController:
    @get("/dashboard")
    async def dashboard(self) -> dict:
        return {"panel": "admin"}

@module(controllers=[AdminController])
class AppModule:
    pass

app = LaurenFactory.create(AppModule)

In production, replace the in-memory USERS dict with a database lookup and store passwords as hashes via BcryptHasher or Argon2Hasher (never plaintext).

Challenge handler

The guard itself raises UnauthorizedError (401). Pair it with basic_auth_challenge_handler in global_exception_handlers to attach WWW-Authenticate: Basic realm="...", charset="UTF-8" to every 401 so browsers show the native credential dialog:

from lauren_guards import basic_auth_challenge_handler

app = LaurenFactory.create(
    AppModule,
    global_exception_handlers=[basic_auth_challenge_handler],
)

The handler reads the realm the guard recorded on the request, falling back to "lauren".

Browser prompt

Browsers automatically show a username/password dialog when they receive a 401 + WWW-Authenticate: Basic realm="..." response, which makes Basic auth useful for quick admin areas without a login form.

Security note

Basic auth transmits the password base64-encoded — never use it without TLS (HTTPS) in production.