当在Flask中使用HTTP身份验证时,标准的401响应

33
在 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 响应。有谁知道我如何使用上面的片段实现它吗?
谢谢。

如果您有不同的原因导致401错误,abort(401, '<为什么访问被拒绝的字符串在此处...>')也可以使用。 - Michael Scheper
2个回答

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)


这需要使用破折号''-''才能在浏览器中正常工作,应该是 ''WWW-Authenticate''。 - Insa
是的,没错。已修复。 - ʇsәɹoɈ

18

Flask的abort直接来自Werkzeug。它是一个可调用对象,会按需引发各种预定义的HTTP异常(HTTPException的子类)。请查看这里的代码获取详细信息。

预定义的Unauthorized(映射到401)仅定义了代码和消息,但不包括WWW-Authenticate标头,而您知道该标头是触发浏览器登录弹窗所必需的。 HTTPException具有的标头在HTTPException.get_headers中硬编码为[('Content-Type', 'text/html')]

因此,要添加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)调用都将引发您的自定义异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接