Flask HTTP 基本认证 - 它是如何工作的?

18 投票
4 回答
41265 浏览
提问于 2025-04-18 01:44

我正在尝试使用Flask和HTTP基本认证来创建一个登录系统。我的问题是,提供用户信息是我自己的责任吗?还是说basicauth会为我创建和访问这些数据库?如果不是的话,我该用什么来做到这一点呢?

4 个回答

1

这里有一个使用Python装饰器函数的Flask基本认证示例。

如果没有认证或者认证错误,它会返回401,表示需要进行身份验证。

Flask API

def check_auth(username, password):
    return username == 'username' and password == 'password'

def login_required(f):
    """ basic auth for api """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return jsonify({'message': 'Authentication required'}), 401
        return f(*args, **kwargs)
    return decorated_function

@app.route('/', methods=["GET"])
@login_required
def home():
    return {"Hello": "world"}

在服务器请求时

response = requests.get(url, auth=('username', 'password'))
18

Werkzeug会把Authorization这个头信息解析成request.authorization,它是一个Authorization对象。

出于安全考虑,浏览器通常只有在收到带有WWW-Authenticate头信息的401错误响应后,才会发送这个头信息。而像requests库这样的其他客户端则会直接发送这个头信息。

最简单的示例是一个装饰器,它会检查request.authorization,如果没有设置这个信息,或者凭证无效,就返回401错误。在实际使用中,你应该使用像Flask-LoginFlask-HTTPAuth这样的扩展来管理这个过程。

from functools import wraps
from flask import request

def login_required(f):
    @wraps(f)
    def wrapped_view(**kwargs):
        auth = request.authorization
        if not (auth and check_auth(auth.username, auth.password)):
            return ('Unauthorized', 401, {
                'WWW-Authenticate': 'Basic realm="Login Required"'
            })

        return f(**kwargs)

    return wrapped_view

@app.route('/secret')
@login_required
def secret():
    return f'Logged in as {request.authorization.username}.'
import requests
response = requests.get('http://127.0.0.1:5000/secret', auth=('world', 'hello'))
print(response.text)
# Logged in as world.
20

Flask-HTTPAuth这个扩展(我就是作者,嘿嘿)让实现HTTP基本认证变得简单。你不需要直接处理request.authorization的数据,而是可以设置一些回调函数,把认证的逻辑放进去。

关于你提到的数据库问题,Flask-HTTPAuth并不假设你的用户是怎么存储的。你需要自己提供获取用户和验证密码的逻辑。

21

Werkzeug可以帮你解码基本的授权头信息,把用户名和密码提取出来。接下来你可以决定如何使用这些信息。

request.authorization属性会返回一个Authorization对象。对于基本的认证头信息,这个对象里只会包含usernamepassword

Flask-Login这样的项目可以帮助你管理更复杂的登录过程,使用基本的授权,并且可以和你提供的用户模型结合起来。这个用户模型可以存储在数据库里,或者你想要的其他地方。

你还可以看看Flask-Security,这是一个更全面的安全包,它结合了Flask-Login和其他工具,提供基本认证和基于会话的登录功能。

撰写回答