Flask中使用HTTP认证时的标准401响应

33 投票
2 回答
42940 浏览
提问于 2025-04-17 04:54

在Flask中,我正在使用以下代码片段来启用HTTP身份验证:

def authenticate():
    return Response('<Why access is denied string goes here...>', 401, {'WWW-Authenticate':'Basic realm="Login Required"'})

在我之前使用Flask的经验中,如果有人输入的凭证不正确,我想让他们知道,我可以直接调用:

abort(401)

这样可以给出基本的apache 401响应。有没有人知道我怎么能把这个和上面的代码片段结合起来?

谢谢

2 个回答

18

Flask中的abort功能是直接来自Werkzeug的。它是一个可以调用的对象,可以根据需要抛出各种预定义的HTTP异常(这些异常都是HTTPException的子类)。想了解更多细节,可以查看这段代码这里

其中预定义的Unauthorized(对应的状态码是401)只定义了状态码和一条消息,但没有定义WWW-Authenticate这个头信息。你知道的,这个头信息是用来在浏览器中触发登录弹窗的。HTTPException的头信息是硬编码的,具体内容是[('Content-Type', 'text/html')],在HTTPException.get_headers中定义。

所以,如果想要添加WWW-Authenticate头信息,就需要创建一个自己的Unauthorized子类,重写get_headers函数,最后用这个新的类更新abort.mapping字典。

from flask import abort
from werkzeug.exceptions import Unauthorized

class MyUnauthorized(Unauthorized):
    description = '<Why access is denied string goes here...>'
    def get_headers(self, environ):
        """Get a list of headers."""
        return [
            ('Content-Type', 'text/html'),
            ('WWW-Authenticate', 'Basic realm="Login required"'),
        ]

abort.mapping.update({401: MyUnauthorized})

这样,所有的abort(401)调用都会抛出你自定义的异常。

45

在Flask中,自定义错误响应其实非常简单。你只需要创建一个函数,这个函数的唯一参数是HTTP错误状态码,然后让它返回一个flask.Response实例,最后用@app.errorhandler这个装饰器来装饰它。

@app.errorhandler(401)
def custom_401(error):
    return Response('<Why access is denied string goes here...>', 401, {'WWW-Authenticate':'Basic realm="Login Required"'})

之后,你就可以随心所欲地使用abort(401)了。

撰写回答