Middleware

Этот документ объясняет все компоненты промежуточного ПО, которые поставляются с Django. Для получения информации о том, как их использовать и как написать свое собственное промежуточное ПО, смотрите middleware usage guide.

Доступное промежуточное программное обеспечение

Промежуточное программное обеспечение для кэша

class UpdateCacheMiddleware[исходный код]
class FetchFromCacheMiddleware[исходный код]

Включить общий кэш сайта. Если они включены, то каждая страница на Django будет кэшироваться столько времени, сколько определено настройкой CACHE_MIDDLEWARE_SECONDS. См. параметр cache documentation.

«Общее» промежуточное программное обеспечение

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()
    
  • Устанавливает заголовок Content-Length для непотоковых ответов.

CommonMiddleware.response_redirect_class

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

class BrokenLinkEmailsMiddleware[исходный код]

Промежуточное программное обеспечение GZip

class GZipMiddleware[исходный код]
max_random_bytes

По умолчанию значение равно 100. Подкласс GZipMiddleware и переопределите атрибут, чтобы изменить максимальное количество случайных байт, включаемых в сжатые ответы.

Примечание

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

Для защиты от атак в Django реализована техника, называемая Heal The Breach (HTB). Она добавляет в каждый ответ до 100 байт (см. max_random_bytes) случайных байтов, чтобы сделать атаки менее эффективными.

BREACH paper (PDF)`_Для `breachattack.com Heal The Breach (HTB) paper м

Changed in Django 4.2:

Добавлена защита от атаки BREACH.

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

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

Он НЕ будет сжимать содержимое, если верно хотя бы одно из следующих условий:

  • Длина тела содержимого составляет менее 200 байт.
  • В ответе уже установлен заголовок Content-Encoding.
  • Запрос (браузер) не отправил заголовок Accept-Encoding, содержащий gzip.

Если ответ содержит заголовок ETag, то ETag делается слабым, чтобы соответствовать RFC 9110#section-8.8.1.

Вы можете применить сжатие GZip к отдельным представлениям с помощью декоратора gzip_page().

Условное промежуточное программное обеспечение GET

class ConditionalGetMiddleware[исходный код]

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

Locale middleware

class LocaleMiddleware[исходный код]

Обеспечивает выбор языка на основе данных из запроса. Это настраивает содержимое для каждого пользователя. См. internationalization documentation.

LocaleMiddleware.response_redirect_class

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

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

class MessageMiddleware[исходный код]

Включает поддержку сообщений на основе cookie и сессий. См. messages documentation.

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

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

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

class SecurityMiddleware[исходный код]

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

Строгая транспортная безопасность HTTP

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

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

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

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

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

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

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

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

Примечание

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

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

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

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

  • Полный URL: отправлять весь URL в заголовке Referer. Например, если пользователь посещает https://example.com/page.html, заголовок Referer будет содержать "https://example.com/page.html".
  • Только происхождение: отправлять только «происхождение» в реферере. Происхождение состоит из схемы, хоста и (опционально) номера порта. Например, если пользователь посещает https://example.com/page.html, происхождение будет https://example.com/.
  • No referrer: вообще не отправлять заголовок Referer.

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

  • Одинаковое происхождение и перекрестное происхождение: ссылка с https://example.com/1.html на https://example.com/2.html является одноименной. Ссылка с https://example.com/page.html на https://not.example.com/page.html является перекрестной.
  • Понижение протокола: понижение происходит, если страница, содержащая ссылку, обслуживается через HTTPS, но страница, на которую ведет ссылка, не обслуживается через HTTPS.

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

Когда ваш сайт обслуживается через HTTPS, Django’s CSRF protection system требует наличия заголовка Referer, поэтому полное отключение заголовка Referer будет препятствовать защите от CSRF. Чтобы получить большинство преимуществ отключения заголовков Referer, сохранив при этом защиту CSRF, рассмотрите возможность включения только одноименных рефереров.

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

no-referrer
Указывает браузеру не отправлять реферер для ссылок, нажатых на этом сайте.
no-referrer-when-downgrade
Указывает браузеру отправлять полный URL в качестве реферера, но только в том случае, если не происходит понижение протокола.
origin
Указывает браузеру отправлять в качестве реферера только источник, а не полный URL.
origin-when-cross-origin
Указывает браузеру отправлять полный URL в качестве реферера для одноименных ссылок и только источник для перекрестных ссылок.
same-origin
Указывает браузеру отправлять полный URL, но только для ссылок одного происхождения. Для перекрестных ссылок реферер не отправляется.
strict-origin
Указывает браузеру отправлять только источник, а не полный URL, и не отправлять referrer, когда происходит понижение протокола.
strict-origin-when-cross-origin
Указывает браузеру отправлять полный URL, если ссылка является одноименной и не происходит понижение протокола; отправлять только источник, если ссылка является перекрестной и не происходит понижение протокола; и не отправлять referrer, если происходит понижение протокола.
unsafe-url
Указывает браузеру всегда отправлять полный URL в качестве реферера.

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

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

Политика кросс-оригинальных открывателей

Некоторые браузеры имеют возможность изолировать окна верхнего уровня от других документов, помещая их в отдельную группу контекста просмотра, основанную на значении заголовка Cross-Origin Opener Policy (COOP). Если изолированный таким образом документ открывает всплывающее окно с перекрестной ориентацией, свойство window.opener этого всплывающего окна будет null. Изоляция окон с помощью COOP - это защита в глубину от кросс-оригинальных атак, особенно таких, как Spectre, которые позволяли проникать в данные, загруженные в общий контекст просмотра.

SecurityMiddleware может установить заголовок Cross-Origin-Opener-Policy за вас, основываясь на настройке SECURE_CROSS_ORIGIN_OPENER_POLICY. Допустимыми значениями для этой настройки являются:

same-origin
Изолирует контекст просмотра исключительно для документов одного происхождения. Документы перекрестного происхождения не загружаются в тот же контекст просмотра. Это стандартный и наиболее безопасный вариант.
same-origin-allow-popups
Изолирует контекст просмотра от документов одного происхождения или тех, которые либо не устанавливают COOP, либо отказываются от изоляции, устанавливая COOP равным unsafe-none.
unsafe-none
Позволяет добавить документ в контекстную группу просмотра его открывателя, если сам открыватель не имеет COOP same-origin или same-origin-allow-popups.

X-Content-Type-Options: nosniff

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

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

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

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

Перенаправление SSL

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

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

Примечание

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

Если параметр SECURE_SSL_HOST имеет значение, все перенаправления будут отправляться на этот хост вместо первоначально запрошенного хоста.

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

Примечание

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

Промежуточное ПО для сессий

class SessionMiddleware[исходный код]

Включает поддержку сеанса. См. session documentation.

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

class CurrentSiteMiddleware[исходный код]

Добавляет атрибут site, представляющий текущий сайт, к каждому входящему объекту HttpRequest. См. sites documentation.

Промежуточное программное обеспечение для аутентификации

class AuthenticationMiddleware

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

class RemoteUserMiddleware

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

class PersistentRemoteUserMiddleware

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

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

class CsrfViewMiddleware[исходный код]

Добавляет защиту от подделки межсайтовых запросов, добавляя скрытые поля формы в POST-формы и проверяя запросы на правильное значение. См. Cross Site Request Forgery protection documentation.

X-Frame-Options промежуточное программное обеспечение

class XFrameOptionsMiddleware[исходный код]

Простой clickjacking protection via the X-Frame-Options header.

Заказ промежуточного программного обеспечения

Вот несколько подсказок относительно порядка следования различных классов промежуточного программного обеспечения Django:

  1. SecurityMiddleware

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

  2. UpdateCacheMiddleware

    Перед теми, которые изменяют заголовок Vary (SessionMiddleware, GZipMiddleware, LocaleMiddleware).

  3. GZipMiddleware

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

    После UpdateCacheMiddleware: Модифицирует заголовок Vary.

  4. SessionMiddleware

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

    После UpdateCacheMiddleware: Модифицирует заголовок Vary.

  5. ConditionalGetMiddleware

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

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

  6. LocaleMiddleware

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

  7. CommonMiddleware

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

    Близко к началу: перенаправляет, когда APPEND_SLASH или PREPEND_WWW установлены в True.

    После SessionMiddleware, если вы используете CSRF_USE_SESSIONS.

  8. CsrfViewMiddleware

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

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

    После SessionMiddleware, если вы используете CSRF_USE_SESSIONS.

  9. AuthenticationMiddleware

    После SessionMiddleware: использует сессионное хранилище.

  10. MessageMiddleware

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

  11. FetchFromCacheMiddleware

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

  12. FlatpageFallbackMiddleware

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

  13. RedirectFallbackMiddleware

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

Вернуться на верх