Стандартный ответ 401 при использовании HTTP auth в колбе

В фляге я использую следующий snippet, чтобы включить HTTP-аутентификацию:

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

Теперь, в моем прошлом опыте с Flask, если кто-то учетные данные неверны, и я хочу сообщить им, что могу просто позвонить:

abort(401)

Это дает вам базовый ответ apache 401. Кто-нибудь знает, как я могу реализовать это с помощью фрагмента выше?

Спасибо

Ответы

Ответ 1

Пользовательские ответы об ошибках в Flask действительно довольно просты. Создайте функцию, единственным аргументом которой является код состояния ошибки HTTP, чтобы вернуть экземпляр flask.Response и украсить его @app.errorhandler.

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

Затем вы можете использовать abort(401) в своем сердечном содержимом.

Ответ 2

Колба abort поступает непосредственно от Werkzeug. Это вызываемый объект, который по запросу вызывает различные предопределенные HTTP-исключения (подклассы HTTPException). Подробнее см. Код здесь.

Предопределенный Unauthorized (который сопоставляется с 401) определяет только код и сообщение, но не заголовок WWW-Authenticate, который, как вам известно, должен запускать всплывающее окно входа в браузер. Заголовки a 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) поднимут ваше настраиваемое исключение.