Среднесвязь
В данном документе объясняются все компоненты среднесвязи, которые поставляются с Django. Информацию о том, как их использовать и как написать собственную среднесвязь, см. в руководстве по использованию среднесвязи.
Доступная среднесвязь
Среднесвязь кэша
-
class UpdateCacheMiddleware
-
class FetchFromCacheMiddleware
Включите кэширование для всего сайта. Если эти параметры включены, каждая страница, работающая на Django, будет кэшироваться до тех пор, пока это определено параметром CACHE_MIDDLEWARE_SECONDS. Смотрите документацию по кэшу.
Среднесвязь «Общие»
-
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
- Отправляет уведомления по электронной почте о нерабочих ссылках адресатам в
MANAGERS(см. Руководство по управлению отчётами об ошибках).
Среднесвязь GZip
-
class GZipMiddleware -
-
max_random_bytes -
По умолчанию 100. Подкласс
GZipMiddlewareи переопределение атрибута для изменения максимального числа случайных байтов, которые включаются в сжатые ответы.
-
Примечание
Исследователи в области безопасности обнаружили, что при использовании методов сжатия (включая GZipMiddleware) на веб-сайте сайт может быть уязвим к ряду возможных атак.
Для снижения уязвимости Django реализует технику под названием Heal The Breach (HTB). Она добавляет до 100 байтов (см. max_random_bytes) случайных байтов к каждому ответу, чтобы уменьшить эффективность атак.
Дополнительную информацию см. в статье BREACH (PDF), breachattack.com и статье Heal The Breach (HTB).
Была добавлена защита от атаки BREACH.
Среднесвязь django.middleware.gzip.GZipMiddleware сжимает содержимое для браузеров, которые понимают сжатие GZip (все современные браузеры).
Эта среднесвязь должна быть размещена перед любой другой среднесвязью, которой необходимо читать или записывать тело ответа, чтобы сжатие произошло позже.
Она НЕ будет сжимать содержимое, если верно хотя бы одно из следующих утверждений:
- Тело содержимого меньше 200 байтов.
- Ответ уже установил заголовок
Content-Encoding. - Запрос (браузер) не отправил заголовок
Accept-Encodingсодержащийgzip.
Если у ответа есть заголовок ETag то ETag делается слабым, чтобы соответствовать RFC 9110#section-8.8.1.
Вы можете применить сжатие GZip к отдельным представлениям, используя декоратор gzip_page().
Среднесвязь условного получения
-
class ConditionalGetMiddleware
Обрабатывает условные операции GET. Если ответ не содержит заголовок ETag, среднесвязь добавляет его, если необходимо. Если у ответа есть заголовок ETag или Last-Modified, а у запроса есть If-None-Match или If-Modified-Since, то ответ заменяется на HttpResponseNotModified.
Среднесвязь локали
-
class LocaleMiddleware
Включает выбор языка на основе данных из запроса. Настраивает содержимое для каждого пользователя. Смотрите документацию по интернационализации.
-
LocaleMiddleware.response_redirect_class
По умолчанию HttpResponseRedirect. Подкласс LocaleMiddleware и переопределение атрибута для настройки перенаправлений, выполняемых среднесвязью.
Среднесвязь сообщений
-
class MessageMiddleware
Включает поддержку сообщений на основе файлов cookie и сессий. Смотрите документацию по сообщениям.
Среднесвязь безопасности
Предупреждение
Если ваша среда развертывания позволяет, рекомендуется, чтобы ваш веб-сервер выполнял функции, предоставляемые среднесвязью SecurityMiddleware. Таким образом, если есть запросы, которые не обслуживаются Django (например, статические медиафайлы или загруженные пользователем файлы), они будут иметь ту же защиту, что и запросы к вашему приложению Django.
-
class SecurityMiddleware
Среднесвязь django.middleware.security.SecurityMiddleware обеспечивает ряд улучшений безопасности в цикле запроса/ответа. Каждый из них может быть независимо включен или выключен с помощью параметра.
SECURE_CONTENT_TYPE_NOSNIFFSECURE_CROSS_ORIGIN_OPENER_POLICYSECURE_HSTS_INCLUDE_SUBDOMAINSSECURE_HSTS_PRELOADSECURE_HSTS_SECONDSSECURE_REDIRECT_EXEMPTSECURE_REFERRER_POLICYSECURE_SSL_HOSTSECURE_SSL_REDIRECT
HTTP Strict Transport Security
Для сайтов, которые должны быть доступны только через HTTPS, вы можете инструктировать современные браузеры отказываться от подключения к вашему доменному имени через небезопасное соединение (на определённый период времени), установив заголовок “Strict-Transport-Security”. Это снижает уязвимость к некоторым атакам SSL-stripping man-in-the-middle (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.
Политика Referrer
Браузеры используют заголовок Referer для отправки информации на сайт о том, как пользователи туда попали. Когда пользователь нажимает на ссылку, браузер отправляет полный URL страницы, на которой размещена ссылка, в качестве referer. Хотя это может быть полезно для некоторых целей, таких как определение того, кто ссылается на ваш сайт, это также может вызвать проблемы с конфиденциальностью, сообщая одному сайту о посещении пользователем другого сайта.
Некоторые браузеры имеют возможность принимать подсказки о том, должны ли они отправлять заголовок HTTP Referer при нажатии пользователем ссылки; эта подсказка предоставляется через заголовок Referrer-Policy. Этот заголовок может предложить браузерам любое из трех поведений:
- Полный URL: отправляет весь URL в заголовке
Referer. Например, если пользователь посещаетhttps://example.com/page.html, заголовокRefererбудет содержать"https://example.com/page.html". - Только Origin: отправляет только «origin» в заголовке referrer. Origin состоит из схемы, хоста и (необязательно) номера порта. Например, если пользователь посещает
https://example.com/page.html, origin будетhttps://example.com/. - Без referrer: вообще не отправляет заголовок
Referer.
Существуют два типа условий, о которых этот заголовок может сообщать браузеру:
- Один и тот же origin или разные origins: ссылка из
https://example.com/1.htmlнаhttps://example.com/2.html— одинаковый origin. Ссылка изhttps://example.com/page.htmlнаhttps://not.example.com/page.html— разные origins. - Понижение протокола: понижение происходит, если страница, содержащая ссылку, обслуживается через HTTPS, но страница, на которую ведет ссылка, — не через HTTPS.
Предупреждение
Когда ваш сайт обслуживается через HTTPS, система защиты CSRF Django Django’s CSRF protection system требует наличия заголовка Referer, поэтому полное отключение заголовка Referer повлияет на защиту CSRF. Для получения большинства преимуществ от отключения заголовков Referer при одновременном сохранении защиты CSRF, рассмотрите возможность включения только referrers одного origin.
SecurityMiddleware может установить заголовок Referrer-Policy для вас на основе настройки SECURE_REFERRER_POLICY (обратите внимание на правописание: браузеры отправляют заголовок Referer при нажатии пользователем ссылки, но заголовок, информирующий браузер о необходимости сделать это, пишется как Referrer-Policy). Допустимые значения для этой настройки:
-
no-referrer - Инструктирует браузер не отправлять referrer для ссылок, нажатых на этом сайте.
-
no-referrer-when-downgrade - Инструктирует браузер отправлять полный URL в качестве referrer, но только в случае, если не происходит понижение протокола.
-
origin - Инструктирует браузер отправлять только origin, а не полный URL, в качестве referrer.
-
origin-when-cross-origin - Инструктирует браузер отправлять полный URL для ссылок одного origin и только origin для ссылок разных origins.
-
same-origin - Инструктирует браузер отправлять полный URL, но только для ссылок одного origin. Для ссылок разных origins referrer не будет отправлен.
-
strict-origin - Инструктирует браузер отправлять только origin, а не полный URL, и не отправлять referrer при понижении протокола.
-
strict-origin-when-cross-origin - Инструктирует браузер отправлять полный URL, если ссылка является ссылкой одного origin и не происходит понижение протокола; отправлять только origin, если ссылка является ссылкой разных origins и не происходит понижение протокола; и не отправлять referrer при понижении протокола.
-
unsafe-url - Инструктирует браузер всегда отправлять полный URL в качестве referrer.
Неизвестные значения политики
В случае, если значение политики неизвестно пользовательскому агенту, можно указать несколько значений политики для обеспечения резервного варианта. Последнее указанное значение, которое понимается, имеет приоритет. Для поддержки этого можно использовать итерируемый объект или строку, разделенную запятыми, с настройкой SECURE_REFERRER_POLICY.
Политика Cross-Origin Opener
Некоторые браузеры имеют возможность изолировать окна верхнего уровня от других документов, помещая их в отдельную группу контекстов просмотра на основе значения заголовка Cross-Origin Opener Policy (COOP). Если документ, изолированный таким образом, открывает окно всплывающего типа с другим origin, свойство window.opener всплывающего окна будет null. Изоляция окон с помощью COOP — это защита в глубину от атак с разных origins, особенно таких, как Spectre, которые позволяли извлекать данные, загруженные в общую группу контекстов просмотра.
SecurityMiddleware может установить заголовок Cross-Origin-Opener-Policy для вас на основе настройки SECURE_CROSS_ORIGIN_OPENER_POLICY. Допустимые значения для этой настройки:
-
same-origin - Изолирует контекст просмотра исключительно для документов одного origin. Документы разных origins не загружаются в тот же контекст просмотра. Это наиболее безопасный вариант по умолчанию.
-
same-origin-allow-popups - Изолирует контекст просмотра для документов одного origin или тех, которые либо не устанавливают 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
Включает поддержку сессий. См. документацию по сессиям.
Средства обработки сайтов
-
class CurrentSiteMiddleware
Добавляет атрибут site, представляющий текущий сайт, ко всем входящим объектам HttpRequest. См. документацию по сайтам.
Средства обработки аутентификации
-
class AuthenticationMiddleware
Добавляет атрибут user, представляющий текущего пользователя, вошедшего в систему, ко всем входящим объектам HttpRequest. См. Аутентификация при веб-запросах.
-
class RemoteUserMiddleware
Средства обработки для использования аутентификации, предоставленной веб-сервером. См. Инструкции по аутентификации с использованием REMOTE_USER для подробностей использования.
-
class PersistentRemoteUserMiddleware
Средства обработки для использования аутентификации, предоставленной веб-сервером, когда она включена только на странице входа. См. Использование REMOTE_USER только на страницах входа для подробностей использования.
Средства обработки защиты CSRF
-
class CsrfViewMiddleware
Добавляет защиту от межсайтовых поддельных запросов, добавляя скрытые поля в формы POST и проверяя запросы на правильное значение. См. документацию по защите от межсайтовых поддельных запросов.
X-Frame-Options средства обработки
-
class XFrameOptionsMiddleware
Простая защита от кликджекинга с помощью заголовка X-Frame-Options.
Порядок средств обработки
Вот некоторые подсказки по порядку различных классов средств обработки Django:
-
Его следует поместить в начало списка, если вы собираетесь включить перенаправление SSL, так как это позволит избежать прохождения ряда других ненужных средств обработки.
-
Перед теми, которые изменяют заголовок
Vary(SessionMiddleware,GZipMiddleware,LocaleMiddleware). -
Перед любыми средствами обработки, которые могут изменить или использовать тело ответа.
После
UpdateCacheMiddleware: изменяет заголовокVary. -
Перед любыми средствами обработки, которые могут вызвать исключение для запуска представления об ошибке (например,
PermissionDenied), если вы используетеCSRF_USE_SESSIONS.После
UpdateCacheMiddleware: изменяет заголовокVary. -
Перед любыми средствами обработки, которые могут изменить ответ (он устанавливает заголовок
ETag).После
GZipMiddleware, чтобы не вычислять заголовокETagдля сжатых содержимых. -
Один из самых верхних, после
SessionMiddleware(использует данные сессии) иUpdateCacheMiddleware(изменяет заголовокVary). -
Перед любыми средствами обработки, которые могут изменить ответ (он устанавливает заголовок
Content-Length). Средство обработки, которое появляется передCommonMiddlewareи изменяет ответ, должно сброситьContent-Length.Ближе к началу: перенаправляет, если
APPEND_SLASHилиPREPEND_WWWустановлены вTrue.После
SessionMiddlewareесли вы используетеCSRF_USE_SESSIONS. -
Перед любыми средствами обработки представлений, которые предполагают, что атаки CSRF уже обработаны.
Перед
RemoteUserMiddlewareили любыми другими средствами обработки аутентификации, которые могут выполнить вход, и, следовательно, сбросить маркер CSRF, перед вызовом цепочки средств обработки.После
SessionMiddlewareесли вы используетеCSRF_USE_SESSIONS. -
После
SessionMiddleware: использует хранилище сессий. -
После
SessionMiddleware: может использовать хранилище сессий. -
После любых средств обработки, которые изменяют заголовок
Vary: этот заголовок используется для выбора значения для ключа хеша кэша. -
Должен быть в конце, так как это средство обработки последней инстанции.
-
Должен быть в конце, так как это средство обработки последней инстанции.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.2/ref/middleware/