Flask, редирект с HTTP на HTTPS

02.04.2019

По умолчанию метод flask.redirect осуществляет перенаправление запроса по протоколу HTTP.

То есть, если при обращении по адресу /some_url находится что-то в стиле:

flask.redirect('/redirect_url', 302)

то для домена site.com запрос будет перенаправлен на адрес http://site.com/redirect_url.

Если приложение Flask запускается, например, через gunicorn и проксируется с помощью nginx, который все запросы по HTTP отправляет на HTTPS, выставляя 301-ый редирект (что сегодня является довольно распространенной практикой), то, проверив заголовки HTTP–ответов по запросу, можно заметить цепочку редиректов 302->301->200 (вместо ожидаемого 302->200), что не очень хорошо в целом и для поисковых роботов в частности.

Решений подобной «проблемы» довольно много (flask-talisman, проверка flask.request.is_secure и прочие–прочие), но сегодня рассмотрим функцию–велосипед:

import flask

...

def redirect_to_https():
    """
    Перенаправление всех запросов на HTTPS, если включен production режим
    """
    if os.environ['FLASK_ENV'] == 'production':
        return flask.request.url_root.rstrip('/').replace(
            'http://',
            'https://',
            1
        )
    return ''

Предполагается, что режим запуска Flask'а (production или development) управляется с помощью переменной окружения FLASK_ENV.

Пример использования в коде:

flask.redirect(redirect_to_https() + '/redirect_url', 302)

При необходимости (и желании) функцию довольно легко доработать для применения в качестве декоратора.