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.

If the response has an ETag header, the ETag is made weak to comply with 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.

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

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

If your deployment situation allows, it’s usually a good idea to have your front-end web server perform the functionality provided by the SecurityMiddleware. That way, if there are requests that aren’t served by Django (such as static media or user-uploaded files), they will have the same protections as requests to your Django application.

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

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

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

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

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

When enabling HSTS, it’s a good idea to first use a small value for testing, for example, SECURE_HSTS_SECONDS = 3600 for one hour. Each time a web browser sees the HSTS header from your site, it will refuse to communicate non-securely (using HTTP) with your domain for the given period of time. Once you confirm that all assets are served securely on your site (i.e. HSTS didn’t break anything), it’s a good idea to increase this value so that infrequent visitors will be protected (31536000 seconds, i.e. 1 year, is common).

Кроме того, если вы установите параметр 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, то origin будет 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.

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

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). Для этого параметра допустимыми значениями являются:

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 can set the Cross-Origin-Opener-Policy header for you, based on the SECURE_CROSS_ORIGIN_OPENER_POLICY setting. The valid values for this setting are:

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.

Note that in most deployment situations where Django isn’t involved in serving user-uploaded files, this setting won’t help you. For example, if your MEDIA_URL is served directly by your front-end web server (nginx, Apache, etc.) then you’d want to set this header there. On the other hand, if you are using Django to do something like require authorization in order to download files and you cannot set the header using your web server, this setting will be useful.

Перенаправление 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

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

class RemoteUserMiddleware

Middleware for utilizing web server provided authentication. See How to authenticate using REMOTE_USER for usage details.

class PersistentRemoteUserMiddleware

Middleware for utilizing web server provided authentication when enabled only on the login page. See Использование REMOTE_USER только на страницах входа в систему for usage details.

Промежуточное программное обеспечение для защиты от 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

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

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