There isn't a built in way to do this (Quart is agnostic, and Quart-Auth focuses on cookie and basic authentication). However the following will work for header based API keys,
from quart import (
current_app,
has_request_context,
has_websocket_context,
request,
websocket,
)
from werkzeug.exceptions import Unauthorized
def api_key_required(
api_config_key: str = "API_KEY",
) -> Callable:
"""A decorator to restrict route access to requests with an API key.
This should be used to wrap a route handler (or view function) to
enforce that only api key authenticated requests can access it. The
key value is configurable via the app configuration with API_KEY key
used by default. Note that it is important that this decorator be
wrapped by the route decorator and not vice, versa, as below.
.. code-block:: python
@app.route('/')
@api_key_required()
async def index():
...
If the request is not authenticated a
`werkzeug.exceptions.Unauthorized` exception will be raised.
"""
def decorator(func: Callable) -> Callable:
@wraps(func)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
if has_request_context():
api_key = request.headers.get("X-API-Key", "")
elif has_websocket_context():
api_key = websocket.headers.get("X-API-Key", "")
else:
raise RuntimeError("Not used in a valid request/websocket context")
if (compare_digest(api_key, current_app.config[api_config_key])):
return await current_app.ensure_async(func)(*args, **kwargs)
else:
raise Unauthorized()
return wrapper
return decorator
For query string or cookie based API keys request.args
and request.cookies
can be used instead of request.headers
.