• 3.1
  • 5.0
  • 6.1
  • Версия документации: 3.2

Промежуточный слой (Middleware)

Этот раздел описывает промежуточные слои, которые предоставляет Django. Как использовать и создавать свои промежуточные слои, смотрите соответствующий раздел.

Доступные промежуточные слои

Кэширующий промежуточный слой

class UpdateCacheMiddleware
class FetchFromCacheMiddleware

Активирует кэширование для всего сайта. При этом все страницы, которые генерируются Django, будут закэшированы на время, указанное в настройке CACHE_MIDDLEWARE_SECONDS. Смотрите раздел о кэшировании.

«Common» промежуточный слой

class CommonMiddleware

Добавляет несколько полезностей для перфекционистов:

  • Ограничивает доступ для клиентов, которые указанны в настройке DISALLOWED_USER_AGENTS. Настройка должна содержать список скомпилированных регулярных выражений.

  • Меняет URL в соответствии с настройками APPEND_SLASH и PREPEND_WWW.

    Если APPEND_SLASH равна True и вызванный URL не оканчивается на слеш, и он не найден в URLconf, создается новый URL путем добавления слеша в конец. Если новый URL найден в URLconf, Django отправляет перенаправление на этот URL. Иначе начальный URL обрабатывается как обычно.

    Например, foo.com/bar будет перенаправлен на foo.com/bar/, если нет URL-шаблона для foo.com/bar, но есть для foo.com/bar/.

    Если PREPEND_WWW равна True, URL-ы без «www.» будут перенаправлены на URL с добавлением «www.»

    Обе эти настройки предназначены для нормализации URL-ов. Философия такая – URL должен быть уникальным и единым. Технически URL foo.com/bar отличается от foo.com/bar/ – поисковик проиндексирует их как отдельные URL-ы – поэтому хорошей практикой является нормализация URL-ов.

    При необходимости отдельные представления могут быть исключены из поведения APPEND_SLASH с помощью декоратора no_append_slash():

    from django.views.decorators.common import no_append_slash
    
    @no_append_slash
    def sensitive_fbv(request, *args, **kwargs):
        """View to be excluded from APPEND_SLASH."""
        return HttpResponse()
    
    Changed in Django 3.2:

    Support for the no_append_slash() decorator was added.

  • Устанавливает заголовок Content-Length для непотоковых ответов.

CommonMiddleware.response_redirect_class

По умолчанию HttpResponsePermanentRedirect. Можете создать класс наследник CommonMiddleware и переопределить класс ответа, который используется для перенаправления.

class BrokenLinkEmailsMiddleware

GZip промежуточный слой

class GZipMiddleware

Предупреждение

Security researchers recently revealed that when compression techniques (including GZipMiddleware) are used on a website, the site may become exposed to a number of possible attacks. Before using GZipMiddleware on your site, you should consider very carefully whether you are subject to these attacks. If you’re in any doubt about whether you’re affected, you should avoid using GZipMiddleware. For more details, see the the BREACH paper (PDF) and breachattack.com.

Сжимает ответ для браузеров, которые поддерживают GZip (все современные браузеры).

Этот промежуточный слой должен находится перед любым другим промежуточный слоем, который читает или пишет содержимое ответа, чтобы сжатие происходило в самом конце.

Содержимое ответа НЕ будет сжато при следующих условиях:

  • Содержимое ответа меньше 200 байтов.

  • Ответ уже содержит заголовок Content-Encoding.

  • Браузер не отослал в запросе заголовок Accept-Encoding, который содержит gzip.

If the response has an ETag header, the ETag is made weak to comply with RFC 7232 Section 2.1.

Вы можете добавить GZip сжатие для определенных представлений, используя декоратор gzip_page().

Промежуточный слой для обработки условных GET-запросов

class ConditionalGetMiddleware

Обрабатывает условные GET операции. Если ответ содержит заголовки ETag или Last-Modified, и запрос содержит If-None-Match или If-Modified-Since, ответ заменяется на HttpResponseNotModified.

Промежуточный слой локализации

class LocaleMiddleware

Выполняет выбор текущего языка на основе данных из запроса. Меняет содержимое для каждого пользователя отдельно. Смотрите раздел об интернационализации.

LocaleMiddleware.response_redirect_class

По умолчанию HttpResponseRedirect. Можете создать класс наследник LocaleMiddleware и переопределить класс ответа, который используется для перенаправления.

Промежуточный слой сообщений

class MessageMiddleware

Добавляет поддержку сообщений на основе кук или сессии. Смотрите раздел о сообщениях.

Промежуточный слой безопасности

Предупреждение

Если позволяет ситуация с развертыванием, обычно рекомендуется, чтобы ваш интерфейсный веб-сервер выполнял функции, предоставляемые SecurityMiddleware. Таким образом, если есть запросы, которые не обслуживаются Django (например, статические медиафайлы или файлы, загруженные пользователем), они будут иметь ту же защиту, что и запросы к вашему приложению Django.

class SecurityMiddleware

django.middleware.security.SecurityMiddleware предоставляет ряд проверок безопасности при обработке запроса/ответа. Каждая из них может быть выключена/включена насройкой.

HTTP Strict Transport Security

Для сайтов, которые должны быть доступны только по HTTPS, вы можете указать современным браузерам не подключаться к вашему домену по небезопасному подключению (в течении определенного времени), установив заголовок «Strict-Transport-Security». Это уменьшает подверженность MITM атакам.

SecurityMiddleware будет устанавливать этот заголовок для всех HTTPS ответов, если вы укажите в настройке SECURE_HSTS_SECONDS не нулевое значение.

При включении HSTS рекомендуется сначала использовать небольшое значение для тестирования, например, SECURE_HSTS_SECONDS = 3600 на один час. Каждый раз, когда веб-браузер видит заголовок HSTS с вашего сайта, он отказывается обмениваться незащищенным соединением (с использованием HTTP) с вашим доменом в течение определенного периода времени. Как только вы подтвердите, что все ресурсы на вашем сайте обслуживаются безопасно (т. е. HSTS ничего не сломал), рекомендуется увеличить это значение, чтобы нечастые посетители были защищены (обычно 31536000 секунд, т. е. 1 год).

Если вы установите True еще и в SECURE_HSTS_INCLUDE_SUBDOMAINS, SecurityMiddleware``добавит тег ``includeSubDomains к заголовку Strict-Transport-Security. Рекомендуем включить эту настройку (убедитесь, что все поддомены работают по HTTPS), иначе ваш сайт может быть уязвим через небезопасное подключение к поддомену.

Если вы хотите добавить свой сайт в список предварительной загрузки браузера, установите для параметра SECURE_HSTS_PRELOAD значение True. При этом директива preload добавляется к заголовку Strict-Transport-Security.

Предупреждение

HSTS применяется ко всему домену, а не только URL, который вернул ответ с заголовком. Поэтому вам следует использовать его только, если весь домен доступен через HTTPS.

Браузеры, которые поддерживают заголовки HSTS, не позволят пользователям игнорировать предупреждение и подключиться к сайту с устаревшим, самостоятельно подписанным, или неправильным SSL сертификатом. Если вы используете HSTS, убедитесь, что с вашими сертификатами все впорядке!

Примечание

Если ваш сервер находится за балансировщиком нагрузки, или прокси, и заголовок Strict-Transport-Security не добавляется к ответам, это может быть вызвано тем, что Django не определяет, что используется защищенное подключение. Возможно вам следует указать настройку SECURE_PROXY_SSL_HEADER.

Политика рефералов

Браузеры используют «заголовок Referer»__ как способ отправки на сайт информации о том, как на него попали пользователи. Когда пользователь нажимает ссылку, браузер отправляет полный URL-адрес ссылающейся страницы в качестве реферера. Хотя это может быть полезно для некоторых целей (например, для выяснения того, кто ссылается на ваш сайт), это также может вызвать проблемы конфиденциальности, сообщая одному сайту, что пользователь посещал другой сайт.

Некоторые браузеры имеют возможность принимать подсказки о том, следует ли отправлять HTTP-заголовок «Referer», когда пользователь нажимает ссылку; эта подсказка предоставляется через `заголовок Referrer-Policy`__. Этот заголовок может предложить браузерам любое из трех вариантов поведения:

  • Полный URL-адрес: отправьте весь URL-адрес в заголовке «Referer». Например, если пользователь посещает https://example.com/page.html, заголовок Referer будет содержать https://example.com/page.html.

  • Только источник: отправляйте только «источник» в реферере. Источник состоит из схемы, хоста и (необязательно) номера порта. Например, если пользователь посещает https://example.com/page.html, источником будет https://example.com/.

  • Нет реферера: вообще не отправлять заголовок «Referer».

Существует два типа условий, на которые этот заголовок может указать браузеру:

  • Одно и то же происхождение или перекрестное происхождение: ссылка с «https://example.com/1.html» на «https://example.com/2.html» имеет одинаковое происхождение. Ссылка с https://example.com/page.html на https://not.example.com/page.html является перекрестной.

  • Понижение версии протокола: понижение версии происходит, если страница, содержащая ссылку, обслуживается через HTTPS, но страница, на которую имеется ссылка, не обслуживается через HTTPS.

Предупреждение

When your site is served via HTTPS, Django’s CSRF protection system requires the Referer header to be present, so completely disabling the Referer header will interfere with CSRF protection. To gain most of the benefits of disabling Referer headers while also keeping CSRF protection, consider enabling only same-origin referrers.

SecurityMiddleware может установить для вас заголовок Referrer-Policy на основе параметра SECURE_REFERRER_POLICY (обратите внимание на написание: браузеры отправляют заголовок Referer, когда пользователь нажимает ссылку, но заголовок, инструктирующий браузер, следует ли это делать, пишется Referrer-Policy). Допустимые значения для этого параметра:

без реферера

Указывает браузеру не отправлять реферер для ссылок, по которым нажимают на этом сайте.

без реферера при понижении версии

Указывает браузеру отправлять полный URL-адрес в качестве реферера, но только в том случае, если не происходит перехода на более раннюю версию протокола.

происхождение

Указывает браузеру отправлять в качестве реферера только источник, а не полный URL-адрес.

происхождение-когда-перекрестное происхождение

Указывает браузеру отправлять полный URL-адрес в качестве реферера для ссылок с одним и тем же источником и только источник для ссылок с перекрестным источником.

того же происхождения

Указывает браузеру отправлять полный URL-адрес, но только для ссылок одного происхождения. Для ссылок с перекрестным происхождением реферер не будет отправлен.

строгого происхождения

Указывает браузеру отправлять только источник, а не полный URL-адрес, и не отправлять реферер при переходе на более раннюю версию протокола.

строгое происхождение при перекрестном происхождении

Указывает браузеру отправлять полный URL-адрес, если ссылка имеет одно и то же происхождение и не происходит перехода на более раннюю версию протокола; отправлять только источник, если ссылка является перекрестной и не происходит перехода на более раннюю версию протокола; и отсутствие реферера при переходе на более раннюю версию протокола.

небезопасный-url

Указывает браузеру всегда отправлять полный URL-адрес в качестве источника перехода.

Неизвестные значения политики

Если значение политики «неизвестно»__ пользовательскому агенту, можно указать несколько значений политики, чтобы обеспечить запасной вариант. Последнее заданное значение, которое понятно, имеет приоритет. Для поддержки этого можно использовать повторяемую строку или строку, разделенную запятыми, с SECURE_REFERRER_POLICY.

X-Content-Type-Options: nosniff

Некоторые браузеры пытаются угадать тип содержимого(content type) полученных файлов, подменяя заголовок Content-Type. В то время, как такой подход помогает правильно отображать сайты с неправильно настроенных серверов, он может быть и уязвимостью.

Если ваш сайт позволяет пользователям загружать файлы, взломщик может загрузить специальный файл, который будет интерпретирован браузером как HTML или Javascript.

Чтобы запретить браузеру угадывать тип файла и заставить всегда использовать значение из заголовка Content-Type, вы можете передать заголовок X-Content-Type-Options: nosniff. SecurityMiddleware добавит его ко всем ответам, если настройка SECURE_CONTENT_TYPE_NOSNIFF равна True.

Обратите внимание: в большинстве ситуаций развертывания, когда Django не участвует в обслуживании загруженных пользователем файлов, этот параметр вам не поможет. Например, если ваш MEDIA_URL обслуживается непосредственно вашим интерфейсным веб-сервером (nginx, Apache и т. д.), тогда вам нужно установить этот заголовок там. С другой стороны, если вы используете Django для чего-то вроде запроса авторизации для загрузки файлов и не можете установить заголовок с помощью веб-сервера, этот параметр будет полезен.

X-XSS-Protection: 1; mode=block

Some browsers have the ability to block content that appears to be an XSS attack. They work by looking for JavaScript content in the GET or POST parameters of a page. If the JavaScript is replayed in the server’s response, the page is blocked from rendering and an error page is shown instead.

The `X-XSS-Protection header`__ is used to control the operation of the XSS filter.

To enable the XSS filter in the browser, and force it to always block suspected XSS attacks, you can pass the X-XSS-Protection: 1; mode=block header. SecurityMiddleware will do this for all responses if the SECURE_BROWSER_XSS_FILTER setting is True.

Предупреждение

The browser XSS filter is a useful defense measure, but must not be relied upon exclusively. It cannot detect all XSS attacks and not all browsers support the header. Ensure you are still validating and sanitizing all input to prevent XSS attacks.

SSL редирект

Если ваш сайт доступен по HTTP и HTTPS, большинство пользователей будут заходить по незащищенному подключению по умолчанию. Вам следует перенапралять их с HTTP на HTTPS.

Если установить True в SECURE_SSL_REDIRECT, SecurityMiddleware будет перманентно (HTTP 301) перенаправлять все HTTP запросы на HTTPS.

Примечание

Для повышения производительности лучше делать эти перенаправления не в Django, а на балансере нагрузки или прокси, таком как nginx. SECURE_SSL_REDIRECT следует использовать для разработки, чтобы не усложнять локальное окружение.

Если указать значение в настройке SECURE_SSL_HOST, все перенаправления будут выполняться на указанный хост, а не хост из запроса.

Если на сайте есть страницы, которые должны быть доступны по HTTP без перенаправления на HTTPS, вы можете указать в настройке SECURE_REDIRECT_EXEMPT регулярные выражение, которым удовлетворяют необходимые URL-ы.

Примечание

Если ваш сервер находится за балансировщиком нагрузки или прокси, Django может не определяет, что используется защищенное подключение. Возможно вам следует указать настройку SECURE_PROXY_SSL_HEADER.

Промежуточный слой сессии

class SessionMiddleware

Включает поддержку сессии. Смотрите раздел о сессии.

Middleware для сайтов

class CurrentSiteMiddleware

Добавляет атрибут site, который указывает текущий сайт для каждого объекта HttpRequest. Смотрите раздел о поддержке нескольких сайтов.

Промежуточный слой авторизации

class AuthenticationMiddleware

Adds the user attribute, representing the currently-logged-in user, to every incoming HttpRequest object. See Authentication in Web requests.

class RemoteUserMiddleware

Промежуточное программное обеспечение для использования веб-сервера обеспечивает аутентификацию. Подробности использования см. в Authentication using REMOTE_USER.

class PersistentRemoteUserMiddleware

Промежуточное ПО для использования веб-сервера обеспечивало аутентификацию, если она включена только на странице входа в систему. Подробности использования см. в Использование REMOTE_USER только на странице авторизации.

Промежуточный слой для CSRF защиты

class CsrfViewMiddleware

Включает CSRF защиту, добавляя скрытое поле в POST формы и проверяя значение при запросе. Смотрите раздел о Cross Site Request Forgery защите.

Промежуточный слой X-Frame-Options

class XFrameOptionsMiddleware

Добавляет простую защиту от «clickjacking», используя заголовок X-Frame-Options.

Порядок промежуточных слоёв

Несколько советов о порядке промежуточных слоёв Django:

  1. SecurityMiddleware

    Должен следовать в начале списка промежуточных слоев, если вы используете SSL перенаправление, чтобы избежать обработки небезопасного запроса другими промежуточными слоями.

  2. UpdateCacheMiddleware

    Добавлять перед промежуточными слоями, которые могут изменить заголовок Vary (SessionMiddleware, GZipMiddleware, LocaleMiddleware).

  3. GZipMiddleware

    Добавлять перед промежуточными слоями, которые могут изменять или читать тело ответа.

    После UpdateCacheMiddleware: изменяет заголовок Vary.

  4. SessionMiddleware

    Перед любым промежуточным программным обеспечением, которое может вызвать исключение для запуска представления ошибок (например, PermissionDenied), если вы используете CSRF_USE_SESSIONS.

    После UpdateCacheMiddleware: изменяет заголовок Vary.

  5. ConditionalGetMiddleware

    Перед любым промежуточным слоем, который может изменять ответ (вычисляет ETags).

    После GZipMiddleware, чтобы заголовок ETag не вычислялся для сжатого ответа.

  6. LocaleMiddleware

    Следует одним из первых, после SessionMiddleware (использует сессию) и CacheMiddleware (изменяет заголовок Vary).

  7. CommonMiddleware

    Перед любым промежуточным программным обеспечением, которое может изменить ответ (оно устанавливает заголовок Content-Length). Промежуточное программное обеспечение, которое появляется перед CommonMiddleware и изменяет ответ, должно сбросить Content-Length.

    Ближе к верху: выполняет перенаправление при APPEND_SLASH или PREPEND_WWW равном True.

    После SessionMiddleware: использует сессию.

  8. CsrfViewMiddleware

    Перед любым промежуточным слоем, который предполагает, что CSRF защита уже выполнена.

    До RemoteUserMiddleware или любого другого промежуточного программного обеспечения аутентификации, которое может выполнять вход в систему и, следовательно, менять токен CSRF перед вызовом цепочки промежуточного программного обеспечения.

    После SessionMiddleware: использует сессию.

  9. AuthenticationMiddleware

    После SessionMiddleware: использует сессию.

  10. MessageMiddleware

    После SessionMiddleware: может использовать сессию для хранения данных.

  11. FetchFromCacheMiddleware

    После любого промежуточного слоя, который может изменить заголовок Vary: его значение используется для генерации ключа в кеше.

  12. FlatpageFallbackMiddleware

    Должен быть в низу.

  13. RedirectFallbackMiddleware

    Должен быть в низу.

Back to Top