HTTP Authentication for Flask
Flask-HTTPAuth is a Flask extension that simplifies the use of HTTP authentication with Flask routes. It currently supports Basic, Digest, and Token authentication schemes. The library is actively maintained with regular releases, typically every few months, ensuring compatibility with the latest Flask versions and addressing security concerns.
Warnings
- breaking Version 4.0.0 dropped support for Python 2.x. Applications running on Python 2 must either remain on `flask-httpauth<4.0.0` or upgrade to Python 3.
- breaking In version 4.0.0, the `auth.username()` method was renamed to `auth.current_user()` to align with more generic authentication contexts (e.g., token-based authentication where the 'username' might not be directly applicable).
- gotcha For secure password handling, it is highly recommended to use the `@auth.verify_password` decorator with hashed passwords (e.g., `werkzeug.security.generate_password_hash`, `check_password_hash`). Relying on `@auth.get_password` with plain-text passwords is insecure and should be avoided.
- gotcha When using `HTTPDigestAuth`, Flask's `SECRET_KEY` configuration must be set, and for robust security, server-side sessions should be used instead of the default client-side (cookie-based) sessions to prevent exposure of challenge data.
- breaking The default value of `auth.login_message` changed from a generic 'Login Required' string to `None` in version 4.0.0. If your application relied on the default message being displayed, it will no longer appear unless explicitly set.
Install
-
pip install Flask-HTTPAuth
Imports
- HTTPBasicAuth
from flask_httpauth import HTTPBasicAuth
- HTTPDigestAuth
from flask_httpauth import HTTPDigestAuth
- HTTPTokenAuth
from flask_httpauth import HTTPTokenAuth
Quickstart
import os
from flask import Flask, jsonify
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash
app = Flask(__name__)
auth = HTTPBasicAuth()
# In a real application, fetch from a database or secure configuration
users = {
"john": generate_password_hash(os.environ.get('JOHN_PASSWORD', 'hello')),
"susan": generate_password_hash(os.environ.get('SUSAN_PASSWORD', 'bye'))
}
@auth.verify_password
def verify_password(username, password):
if username in users and \
check_password_hash(users.get(username), password):
return username
return None
@app.route('/')
@auth.login_required
def index():
return f"Hello, {auth.current_user()}! You are authenticated."
@app.route('/public')
def public_route():
return "This is a public route."
if __name__ == '__main__':
# Example of setting environment variables for quick testing:
# export JOHN_PASSWORD=secret_john
# export SUSAN_PASSWORD=secret_susan
app.run(debug=True)