Bearer Token Guard¶
bearer_token(*, verify, realm, error_description) — validates HTTP Bearer tokens (RFC 6750) with a caller-supplied verifier function.
Signature¶
def bearer_token(
*,
verify: Callable[[str], AuthUser | None] | Callable[[str], Awaitable[AuthUser | None]],
realm: str = "lauren",
error_description: bool = False,
) -> type:
...
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
verify |
callable | — | Sync or async (token) -> AuthUser \| None. Return an AuthUser to allow, None to reject. |
realm |
str |
"lauren" |
Realm surfaced in error responses. |
error_description |
bool |
False |
Include a short machine-readable reason in the UnauthorizedError detail (missing_token, malformed_header, invalid_token, verifier_error). |
Returns: An @injectable(scope=SINGLETON) guard class.
Usage¶
from lauren import LaurenFactory, controller, get, module, use_guards
from lauren_guards import bearer_token, AuthUser
async def verify_token(token: str) -> AuthUser | None:
# Replace with DB/cache lookup
if token == "valid-token":
return AuthUser(id="u1", roles=("viewer",), scopes=("read",))
return None
BearerGuard = bearer_token(verify=verify_token)
@use_guards(BearerGuard)
@controller("/api")
class ApiController:
@get("/data")
async def data(self) -> dict:
return {"ok": True}
@module(controllers=[ApiController])
class AppModule:
pass
app = LaurenFactory.create(AppModule)
Accessing the authenticated user¶
After successful authentication the guard stores the AuthUser on request.state.user:
from lauren import Request
@controller("/api")
class ApiController:
@get("/me")
async def me(self, request: Request) -> dict:
user = request.state.get("user") # AuthUser instance
return {"id": user.id, "roles": list(user.roles)}
You can also use the explicit helpers get_user(request) / set_user(request, user) — see the reference.
Rejection behaviour¶
When the token is missing, malformed, or rejected by verify, the guard raises UnauthorizedError (HTTP 401). The guard itself does not emit WWW-Authenticate — set error_description=True to include a reason in the error detail if your API needs it.
Choosing a realm¶
The realm value appears in the error detail and any custom error handlers you attach. Pick something identifiable (e.g. "Customer API") so clients can tell which credential they need.