Средства промежуточного слоя
В этом документе объясняются все компоненты средств промежуточного слоя, поставляемые с Django. Информацию о том, как их использовать и как написать собственные средства промежуточного слоя, см. в руководстве по использованию средств промежуточного слоя.
Доступные средства промежуточного слоя
Средства промежуточного слоя кэширования
-
class UpdateCacheMiddleware[source]
-
class FetchFromCacheMiddleware[source]
Включить кэширование на сайте. Если они включены, каждая страница Django будет кэшироваться на срок, определяемый настройкой CACHE_MIDDLEWARE_SECONDS. Смотрите документацию по кэшированию.
Средства промежуточного слоя “Общие”
-
class CommonMiddleware[source] -
-
response_redirect_class -
По умолчанию
HttpResponsePermanentRedirect. Подкласс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для ответов, не являющихся потоковыми.
-
class BrokenLinkEmailsMiddleware[source]
- Отправляет электронные письма о ссылках, не работающих, менеджерам
MANAGERS(см. как управлять обработкой ошибок).
Средства промежуточного слоя gzip
-
class GZipMiddleware[source] -
-
max_random_bytes -
По умолчанию 100. Подкласс
GZipMiddlewareи перезаписывает атрибут, чтобы изменить максимальное количество случайных байтов, включаемых в сжатые ответы.
-
Примечание
Исследователи в области безопасности выявили, что при использовании методов сжатия (включая GZipMiddleware) на веб-сайте сайт может стать уязвимым для различных атак.
Для смягчения атак Django реализует технику Heal The Breach (HTB). Она добавляет до 100 байтов (см. max_random_bytes) случайных байтов к каждому ответу, чтобы снизить эффективность атак.
Дополнительную информацию см. в документе BREACH (PDF), breachattack.com и статье Heal The Breach (HTB).
Средства промежуточного слоя django.middleware.gzip.GZipMiddleware сжимают контент для браузеров, которые понимают сжатие GZip (все современные браузеры).
Это средство промежуточного слоя должно располагаться перед другими средствами промежуточного слоя, которым необходимо читать или писать тело ответа, чтобы сжатие происходило после этого.
Он НЕ будет сжимать контент, если выполняются следующие условия:
- Тело контента меньше 200 байтов.
- Ответ уже установил заголовок
Content-Encoding. - Запрос (браузер) не отправил заголовок
Accept-Encoding, содержащийgzip.
Если ответ имеет заголовок ETag, то ETag делается слабым для соответствия RFC 9110 Раздел 8.8.1.
Вы можете применить сжатие GZip к отдельным представлениям, используя декоратор gzip_page().
Средства промежуточного слоя условного получения
-
class ConditionalGetMiddleware[source]
Обрабатывает операции условного получения. Если у ответа нет заголовка ETag, средство промежуточного слоя добавляет его при необходимости. Если у ответа есть заголовок ETag или Last-Modified, а у запроса есть заголовки If-None-Match или If-Modified-Since, то ответ заменяется на HttpResponseNotModified.
Вы можете обрабатывать операции условного получения с помощью отдельных представлений, используя декоратор conditional_page().
Средства промежуточного слоя локализации
-
class LocaleMiddleware[source] -
-
response_redirect_class -
По умолчанию
HttpResponseRedirect. ПодклассLocaleMiddlewareи перезаписывает атрибут для настройки перенаправлений, выполняемых средством промежуточного слоя.
-
Включает выбор языка на основе данных из запроса. Настраивает контент для каждого пользователя. См. документацию по интернационализации.
Средства промежуточного слоя сообщений
-
class MessageMiddleware[source]
Включает поддержку сообщений на основе файлов cookie и сеансов. См. документацию по сообщениям.
Средства обеспечения безопасности
Предупреждение
Если ваша среда развертывания позволяет, обычно рекомендуется, чтобы ваш веб-сервер front-end выполнял функции, предоставляемые модулем SecurityMiddleware. Таким образом, если запросы не обрабатываются Django (например, статические медиафайлы или файлы, загруженные пользователем), они будут иметь те же средства защиты, что и запросы к вашему приложению Django.
-
class SecurityMiddleware[source]
Модуль 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”. Это снижает вашу уязвимость к некоторым атакам типа «человек посередине» (MITM) с использованием SSL-стриппинга.
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 страницы-источника в качестве referrer. Хотя это может быть полезно для некоторых целей (например, для определения того, кто ссылается на ваш сайт), это также может вызвать проблемы с конфиденциальностью, сообщая одному сайту, что пользователь посещал другой сайт.
Некоторые браузеры могут принимать подсказки о том, должны ли они отправлять заголовок HTTP Referer, когда пользователь нажимает на ссылку; эта подсказка предоставляется с помощью заголовка Referrer-Policy. Этот заголовок может предложить браузерам любое из трёх поведений:
- Полный URL: отправлять весь URL в заголовке
Referer. Например, если пользователь посещаетhttps://example.com/page.html, заголовокRefererбудет содержать"https://example.com/page.html". - Только домен: отправлять только «домен» в referrer. Домен состоит из схемы, хоста и (необязательно) номера порта. Например, если пользователь посещает
https://example.com/page.html, домен будетhttps://example.com/. - Без 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, система защиты от CSRF Django требует наличия заголовка Referer, поэтому полное отключение заголовка Referer повлияет на защиту от CSRF. Чтобы получить большинство преимуществ отключения заголовков Referer, сохранив при этом защиту от CSRF, рассмотрите возможность включения только однодоменных referrer.
SecurityMiddleware может установить заголовок Referrer-Policy для вас на основе настройки SECURE_REFERRER_POLICY (обратите внимание на написание: браузеры отправляют заголовок Referer при нажатии пользователем ссылки, но заголовок, инструктирующий браузер, как это сделать, пишется Referrer-Policy). Допустимые значения для этой настройки:
-
no-referrer -
Инструктирует браузер не отправлять referrer для ссылок, на которые нажали на этом сайте.
-
no-referrer-when-downgrade -
Инструктирует браузер отправлять полный URL в качестве referrer, но только при отсутствии снижения протокола.
-
origin -
Инструктирует браузер отправлять только домен, а не полный URL, в качестве referrer.
-
origin-when-cross-origin -
Инструктирует браузер отправлять полный URL для однодоменных ссылок и только домен для кроссдоменных.
-
same-origin -
Инструктирует браузер отправлять полный URL, но только для однодоменных ссылок. Для кроссдоменных ссылок referrer не будет отправлен.
-
strict-origin -
Инструктирует браузер отправлять только домен, а не полный URL, и не отправлять referrer при снижении протокола.
-
strict-origin-when-cross-origin -
Инструктирует браузер отправлять полный URL, когда ссылка однодоменная и нет снижения протокола; отправлять только домен, когда ссылка кроссдоменная и нет снижения протокола; и не отправлять referrer при снижении протокола.
-
unsafe-url -
Инструктирует браузер всегда отправлять полный URL в качестве referrer.
Неизвестные значения политики
В тех случаях, когда значение политики неизвестно для пользователя агента, можно указать несколько значений политики, чтобы предоставить резервный вариант. Последнее указанное значение, которое понимается, имеет приоритет. Для поддержки этого можно использовать итерируемый объект или строку, разделённую запятыми, с настройкой 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 предоставляется напрямую вашим веб-сервером front-end (nginx, Apache и т. д.), то вы захотите установить этот заголовок там. С другой стороны, если вы используете Django для чего-то вроде требования авторизации для загрузки файлов и не можете установить заголовок с помощью вашего веб-сервера, эта настройка будет полезной.
Перенаправление на SSL
Если ваш сайт поддерживает как HTTP, так и HTTPS-соединения, по умолчанию большинство пользователей будут иметь небезопасное соединение. Для лучшей безопасности вы должны перенаправлять все HTTP-соединения на HTTPS.
Если вы установите настройку SECURE_SSL_REDIRECT в значение True, SecurityMiddleware будет постоянно (HTTP 301) перенаправлять все HTTP-соединения на HTTPS.
Примечание
По соображениям производительности предпочтительнее выполнять эти перенаправления вне Django, в балансировщике нагрузки front-end или прокси-сервере обратного проксирования, таком как nginx. SECURE_SSL_REDIRECT предназначен для случаев развертывания, где это не вариант.
Если настройка SECURE_SSL_HOST имеет значение, все перенаправления будут отправляться на этот хост вместо первоначально запрошенного хоста.
Если на вашем сайте есть несколько страниц, которые должны быть доступны через HTTP и не перенаправляться на HTTPS, вы можете указать регулярные выражения для соответствия этим URL-адресам в настройке SECURE_REDIRECT_EXEMPT.
Примечание
Если вы развернуты за балансировщиком нагрузки или прокси-сервером обратного проксирования и Django не может понять, когда запрос фактически уже безопасен, вам может потребоваться установить настройку SECURE_PROXY_SSL_HEADER.
Средства промежуточного ПО сеансов
-
class SessionMiddleware[source]
Включает поддержку сеансов. См. документацию по сеансам.
Средства промежуточного ПО сайта
-
class CurrentSiteMiddleware[source]
Добавляет атрибут site, представляющий текущий сайт, к каждому входящему объекту HttpRequest. См. документацию по сайтам.
Средства аутентификации
-
class AuthenticationMiddleware[source]
Добавляет атрибут user, представляющий текущего пользователя, вошедшего в систему, ко всем входящим объектам HttpRequest. См. Аутентификация в веб-запросах.
-
class LoginRequiredMiddleware[source] -
Подклассируйте средство и переопределите следующие атрибуты и методы, чтобы настроить поведение для неавторизованных запросов.
-
redirect_field_name -
По умолчанию
"next".
-
get_login_url()[source] -
Возвращает URL, на который будут перенаправлены неавторизованные запросы. Этот результат является либо
login_url, заданным для декоратораlogin_required()(если неNone), либоsettings.LOGIN_URL.
-
get_redirect_field_name()[source] -
Возвращает имя параметра запроса, содержащего URL, на который пользователь должен быть перенаправлен после успешной авторизации. Этот результат является либо
redirect_field_name, заданным для декоратораlogin_required()(если неNone), либоredirect_field_name. Если возвращаетсяNone, параметр запроса не будет добавлен.
-
Перенаправляет все неавторизованные запросы на страницу входа, за исключением представлений, исключенных с помощью login_not_required(). Страница входа по умолчанию — settings.LOGIN_URL, но может быть настроена.
Включите это средство, добавив его в настройку MIDDLEWARE после AuthenticationMiddleware:
MIDDLEWARE = [
"...",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.auth.middleware.LoginRequiredMiddleware",
"...",
]
Сделайте представление общедоступным, разрешив неавторизованные запросы, с помощью login_not_required(). Например:
from django.contrib.auth.decorators import login_not_required @login_not_required def contact_us(request): ...
Настройте URL входа или имя поля для авторизованных представлений с помощью декоратора login_required(), чтобы установить login_url или redirect_field_name соответственно. Например:
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import View
@login_required(login_url="/books/login/", redirect_field_name="redirect_to")
def book_dashboard(request): ...
@method_decorator(
login_required(login_url="/books/login/", redirect_field_name="redirect_to"),
name="dispatch",
)
class BookMetrics(View):
pass
Убедитесь, что представление входа не требует авторизации.
Чтобы предотвратить бесконечные перенаправления, убедитесь, что вы разрешили неавторизованные запросы для вашего представления входа.
-
class RemoteUserMiddleware[source]
Средство для использования аутентификации, предоставляемой веб-сервером. См. Инструкцию по аутентификации с помощью REMOTE_USER для получения подробной информации об использовании.
-
class PersistentRemoteUserMiddleware[source]
Средство для использования аутентификации, предоставляемой веб-сервером, при включении только на странице входа. См. Использование REMOTE_USER только на страницах входа для получения подробной информации об использовании.
Средство защиты от CSRF
-
class CsrfViewMiddleware[source]
Обеспечивает защиту от межсайтовых поддельных запросов (CSRF), добавляя скрытые поля формы к формам POST и проверяя запросы на соответствие правильного значения. См. Документацию по защите от межсайтовых поддельных запросов.
Вы можете добавить защиту от межсайтовых поддельных запросов (CSRF) к отдельным представлениям с помощью декоратора csrf_protect().
X-Frame-Options средство
-
class XFrameOptionsMiddleware[source]
Порядок подключения миддлверов
Ниже приведены некоторые рекомендации по порядку различных классов миддлверов Django:
-
Его следует поместить в начало списка, если вы собираетесь включить переадресацию на HTTPS, так как это предотвращает прохождение через множество других ненужных миддлверов.
-
Перед теми, которые изменяют заголовок ответа (
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: использует хранилище сессий. -
Новое в Django 5.1.
После
AuthenticationMiddleware: использует объект пользователя. -
После
SessionMiddleware: может использовать хранение на основе сессий. -
После любого миддлвера, который изменяет заголовок
Vary: этот заголовок используется для выбора значения для хэш-ключа кеша. -
Должен быть в конце, так как это миддлвер последней надежды.
-
Должен быть в конце, так как это миддлвер последней надежды.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.2/ref/middleware/