Стандартный ответ 401 при использовании HTTP-аутентификации в колбе - PullRequest
18 голосов
/ 24 октября 2011

В колбе я использую следующий фрагмент , чтобы включить 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 ]

24 голосов
/ 30 ноября 2011

Пользовательские ответы об ошибках действительно просты во 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) для вашего сердца.

13 голосов
/ 23 ноября 2011

Flask's 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) вызовы вызовут ваше пользовательское исключение.

...