Skip to content

lymagics/quart-httpauth

Repository files navigation

quart-httpauth

Basic, Digest and Token (Bearer) HTTP authentication for Quart routes — an async-native port of Flask-HTTPAuth.

The public API mirrors Flask-HTTPAuth: class names, constructor arguments, decorator names, and callback contracts are preserved. Existing Flask-HTTPAuth code transfers by switching flask imports to quart and flask_httpauth to quart_httpauth. The one intentional change is that the request pipeline and every callback are awaited — your verify/role/error callbacks may be written as either def or async def.

Installation

pip install quart-httpauth

The distribution name is quart-httpauth; the import name is quart_httpauth.

Quickstart — Basic auth

from quart import Quart
from quart_httpauth import HTTPBasicAuth
from werkzeug.security import check_password_hash, generate_password_hash

app = Quart(__name__)
auth = HTTPBasicAuth()

users = {
    "susan": generate_password_hash("hunter2"),
}


@auth.verify_password
async def verify_password(username, password):
    if username in users and check_password_hash(users[username], password):
        return username


@app.route("/")
@auth.login_required
async def index():
    return f"Hello, {auth.current_user()}!"

Token (Bearer) auth

from quart import Quart
from quart_httpauth import HTTPTokenAuth

app = Quart(__name__)
auth = HTTPTokenAuth(scheme="Bearer")

tokens = {"secret-token-1": "john"}


@auth.verify_token
async def verify_token(token):
    return tokens.get(token)


@app.route("/")
@auth.login_required
async def index():
    return f"Hello, {auth.current_user()}!"

A custom header works too: HTTPTokenAuth(header="X-API-Key") — there the entire header value is treated as the token with no scheme prefix.

Roles and optional auth

@auth.get_user_roles
async def get_user_roles(user):
    return user.roles


@app.route("/admin")
@auth.login_required(role="admin")
async def admin():
    return "for admins only"


@app.route("/maybe")
@auth.login_required(optional=True)
async def maybe():
    user = auth.current_user()
    return f"Hello, {user or 'anonymous'}!"

Multiple schemes on one route

from quart_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth

basic = HTTPBasicAuth()
token = HTTPTokenAuth()
multi = MultiAuth(basic, token)   # HTTPMultiAuth is an alias


@app.route("/")
@multi.login_required
async def index():
    return f"Hello, {multi.current_user()}!"

See examples/ for runnable apps.

Differences from Flask-HTTPAuth

  • The deprecated hash_password callback, the username() accessor, and the legacy get_password-as-Basic-credential path are not ported. Use verify_password for Basic auth. get_password is retained for HTTPDigestAuth, where it is the primary, non-deprecated mechanism.
  • The per-request user is stored on g.quart_httpauth_user.

License

MIT. Ported from Flask-HTTPAuth (also MIT) by Miguel Grinberg.

About

Simple extension that provides Basic, Digest and Token HTTP authentication for Quart routes

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors