中间件
中间件
这篇文档解释了所有 Django 自带的中间件组件。关于如何使用它们以及如何编写自己的中间件,请参见 中间件使用指南。
可用的中间件
缓存中间件
class UpdateCacheMiddleware[源代码]
class FetchFromCacheMiddleware[源代码]
启用全站缓存。如果启用了这些功能,那么每一个 Django 驱动的页面都会在 CACHE_MIDDLEWARE_SECONDS 配置定义的时间内被缓存。参见 缓存文档。
“通用”中间件
class CommonMiddleware[源代码]
为完美主义者增加了一些便利:
-
禁止 DISALLOWED_USER_AGENTS 配置中的用户代理访问,它应该是一个编译的正则表达式对象列表。
-
根据 APPEND_SLASH 和 PREPEND_WWW 的配置进行 URL 重写。
如果 APPEND_SLASH 为 True,并且初始的 URL 没有以斜线结尾,而且在 URLconf 中也没有找到,那么就会在最后附加一个斜线形成一个新的 URL。如果在 URLconf 中找到了这个新的 URL,那么 Django 会将请求重定向到这个新的 URL。否则,初始的 URL 就会被照常处理。
例如,foo.com/bar 将被重定向到 foo.com/bar/,如果你没有 foo.com/bar 的有效 URL 模式,但 有 foo.com/bar/ 的有效模式。
如果 PREPEND_WWW 为 True,缺乏前导“www. ”的 URL 将被重定向到带有前导“www. ”的同一 URL。
这两个选项都是为了规范 URL。其理念是,每个 URL 应该存在于一个地方,而且只有一个地方。从技术上讲,URL foo.com/bar 与 foo.com/bar/ 是不同的——搜索引擎索引器会将它们视为单独的 URL——所以最好的做法是将 URL 规范化。
如果有必要,可以使用 no_append_slash() 装饰器将个别视图从 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](</read/django-5.1-zh/6d7ac2c5913e5970.md#django.http.HttpResponsePermanentRedirect> "django.http.HttpResponsePermanentRedirect")。子类化 `CommonMiddleware`,并重写该属性来定制中间件发出的重定向。
_class_ `BrokenLinkEmailsMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/middleware/common.py#L118>)
* 向 `manager` 发送失效链接通知邮件(参见 [如何管理错误报告](/read/django-5.1-zh/d083.md))。
### GZip 中间件
_class_ `GZipMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/middleware/gzip.py#L9>)
* `max_random_bytes`
默认为 100。如果需要更改包含在压缩响应中的最大随机字节数,请子类化 `GZipMiddleware` 并重写该属性。
备注
安全研究人员揭示了当在网站上使用压缩技术(包括 `GZipMiddleware`)时,该网站可能会暴露于多种可能的攻击。
为了减轻攻击风险,Django 实施了一种称为 _Heal The Breach (HTB)_ 的技术。它在每个响应中添加了最多 100 字节(参见 max_random_bytes)的随机字节,以减弱攻击的效果。
有关更多详细信息,请参阅 [BREACH 论文 (PDF)](<https://ieeexplore.ieee.org/document/9754554>)、[breachattack.com](<https://www.breachattack.com/>) 和 [Heal The Breach (HTB) 论文](<https://www.breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf>)。
`django.middleware.gzip.GZipMiddleware` 为能理解 GZip 压缩的浏览器(所有现代浏览器)压缩内容。
这个中间件应该放在任何其他需要读取或写入响应体的中间件之前,这样压缩就会在之后发生。
如果以下任何一项为真,它将不会压缩内容:
* 内容主体长度小于 200 字节。
* 响应已经设置了 `Content-Encoding` 头。
* 请求(浏览器)没有发送包含 `gzip` 的 `Accept-Encoding` 头。
如果响应具有 `ETag` 标头,则会将 ETag 标记为弱标记,以符合 [RFC 9110#section-8.8.1](<https://datatracker.ietf.org/doc/html/rfc9110.html#section-8.8.1>)。
你可以使用 [gzip_page()](</read/django-5.1-zh/65eb483beef02b74.md#django.views.decorators.gzip.gzip_page> "django.views.decorators.gzip.gzip_page") 装饰器对单个视图应用 GZip 压缩。
### 条件 GET 中间件
_class_ `ConditionalGetMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/middleware/http.py#L6>)
处理有条件的 GET 操作。如果响应没有 `ETag` 头,中间件会根据需要添加一个。如果响应有 `ETag` 或 `Last-Modified` 头,而请求有 `If-None-Match` 或 `If-Modified-Since`,则响应被一个 [HttpResponseNotModified](</read/django-5.1-zh/6d7ac2c5913e5970.md#django.http.HttpResponseNotModified> "django.http.HttpResponseNotModified") 替换。
### 本地化中间件
_class_ `LocaleMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/middleware/locale.py#L10>)
可以根据请求的数据选择语言。它为每个用户定制内容。请参阅 [国际化文档](<https://docs.djangoproject.com/zh-hans/5.1/topics/i18n/translation>)。
`LocaleMiddleware.response_redirect_class`
默认为 [HttpResponseRedirect](</read/django-5.1-zh/6d7ac2c5913e5970.md#django.http.HttpResponseRedirect> "django.http.HttpResponseRedirect")。子类化 `LocaleMiddleware` 并重写该属性,以自定义中间件发出的重定向。
### 消息中间件
_class_ `MessageMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/contrib/messages/middleware.py#L6>)
启用基于 cookie 和会话的消息支持。参见 [消息文档](/read/django-5.1-zh/d122.md)。
### 安全中间件
警告
如果您的部署情况允许,通常是一个好主意让您的前端 Web 服务器执行由 `SecurityMiddleware` 提供的功能。这样,如果有不由 Django 处理的请求(如静态媒体或用户上传的文件),它们将具有与请求到您的 Django 应用程序相同的保护。
_class_ `SecurityMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/middleware/security.py#L8>)
`django.middleware.security.SecurityMiddleware` 为请求/响应周期提供了若干安全增强功能。每一项都可以通过设置独立地启用或禁用。
* [SECURE_CONTENT_TYPE_NOSNIFF](/read/django-5.1-zh/d165.md#std-setting-SECURE_CONTENT_TYPE_NOSNIFF)
* [SECURE_CROSS_ORIGIN_OPENER_POLICY](/read/django-5.1-zh/d165.md#std-setting-SECURE_CROSS_ORIGIN_OPENER_POLICY)
* [SECURE_HSTS_INCLUDE_SUBDOMAINS](/read/django-5.1-zh/d165.md#std-setting-SECURE_HSTS_INCLUDE_SUBDOMAINS)
* [SECURE_HSTS_PRELOAD](/read/django-5.1-zh/d165.md#std-setting-SECURE_HSTS_PRELOAD)
* [SECURE_HSTS_SECONDS](/read/django-5.1-zh/d165.md#std-setting-SECURE_HSTS_SECONDS)
* [SECURE_REDIRECT_EXEMPT](/read/django-5.1-zh/d165.md#std-setting-SECURE_REDIRECT_EXEMPT)
* [SECURE_REFERRER_POLICY](/read/django-5.1-zh/d165.md#std-setting-SECURE_REFERRER_POLICY)
* [SECURE_SSL_HOST](/read/django-5.1-zh/d165.md#std-setting-SECURE_SSL_HOST)
* [SECURE_SSL_REDIRECT](/read/django-5.1-zh/d165.md#std-setting-SECURE_SSL_REDIRECT)
#### HTTP 严格传输安全
对于只能通过 HTTPS 访问的网站,你可以通过设置 [“Strict-Transport-Security” 头](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security>) 来指示现代浏览器拒绝通过不安全的连接连接到你的域名(在给定的时间内)。这可以减少你受到一些 SSL 剥离中间人(MITM)的攻击。
如果你将 [SECURE_HSTS_SECONDS](/read/django-5.1-zh/d165.md#std-setting-SECURE_HSTS_SECONDS) 设置为一个非零的整数值,`SecurityMiddleware` 将为你在所有 HTTPS 响应中设置这个头。
启用 HSTS 时,建议首先使用一个小的测试值,例如,将 [SECURE_HSTS_SECONDS = 3600](/read/django-5.1-zh/d165.md#std-setting-SECURE_HSTS_SECONDS) 设置为一小时。每次 Web 浏览器看到来自您网站的 HSTS 标头时,它将拒绝在给定的时间段内与您的域名进行非安全通信(使用 HTTP)。一旦您确认您的网站上的所有资源都以安全方式提供(即 HSTS 没有引发任何问题),则建议增加此值,以便不经常访问的访问者也受到保护(常见的值是 31536000 秒,即 1 年)。
此外,如果你将 [SECURE_HSTS_INCLUDE_SUBDOMAINS](/read/django-5.1-zh/d165.md#std-setting-SECURE_HSTS_INCLUDE_SUBDOMAINS) 设置为 `True`,`SecurityMiddleware` 将在 `Strict-Transport-Security` 头中添加 `includeSubDomains` 指令。建议这样做(假设所有的子域都只使用 HTTPS 服务),否则你的网站仍然可能通过不安全的连接到子域而受到攻击。
如果你希望将你的网站提交到 [浏览器预加载列表](<https://hstspreload.org/>) ,请将 [SECURE_HSTS_PRELOAD](/read/django-5.1-zh/d165.md#std-setting-SECURE_HSTS_PRELOAD) 设置为 `True`。这样就会把 `preload` 指令附加到 `Strict-Transport-Security` 头。
警告
HSTS 策略适用于你的整个域,而不仅仅是你设置响应头的 URL。因此,你应该只在你的整个域名只通过 HTTPS 服务时使用它。
适当尊重 HSTS 头的浏览器将拒绝允许用户绕过警告,并连接到使用过期、自签名或其他无效 SSL 证书的网站。如果你使用 HSTS,请确保你的证书处于良好状态,并保持这种状态!
备注
如果你部署在负载平衡器或反向代理服务器后面,而 `Strict-Transport-Security` 头没有被添加到你的响应中,这可能是因为 Django 没有意识到它是在一个安全的连接上;你可能需要设置 [SECURE_PROXY_SSL_HEADER](/read/django-5.1-zh/d165.md#std-setting-SECURE_PROXY_SSL_HEADER) 设置。
#### Referrer 政策
浏览器使用 [referer 头](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer>) 作为向网站发送关于用户如何到达那里的信息的一种方式。当用户点击一个链接时,浏览器将发送链接页面的完整 URL 作为 referrer。虽然这对某些目的来说可能很有用——例如查明谁在链接到你的网站——但它也可能引起隐私问题,因为它告诉一个网站,一个用户正在访问另一个网站。
一些浏览器能够接受关于是否应该在用户点击链接时发送 HTTP `Referer` 头的提示;这种提示通过 [Referrer-Policy 头](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy>) 提供。这个头可以向浏览器建议三种行为中的任何一种:
* 完整 URL:在 `Referer` 头中发送整个URL。例如,如果用户访问 `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 服务的,就会发生降级。
警告
当您的网站通过 HTTPS 提供服务时,[Django 的 CSRF 保护系统](/read/django-5.1-zh/d129.md#how-csrf-works) 需要存在 `Referer` 标头,因此完全禁用 `Referer` 标头将干扰 CSRF 保护。为了获得禁用 `Referer` 标头的大部分好处,同时保留 CSRF 保护,请考虑仅启用同源引用。
`SecurityMiddleware` 可以根据 [SECURE_REFERRER_POLICY](/read/django-5.1-zh/d165.md#std-setting-SECURE_REFERRER_POLICY) 设置,为你设置 `Referrer-Policy` 头(注意拼写:当用户点击链接时,浏览器会发送一个 `Referer` 头,但指示浏览器是否这样做的头是拼写为 `Referrer-Policy`)。该设置的有效值为:
`no-referrer`
指示浏览器对在本网站上点击的链接不发送 referrer。
`no-referrer-when-downgrade`
指示浏览器发送完整的 URL 作为 referrer,但只有在没有发生协议降级的情况下。
`origin`
指示浏览器只发送起源,而不是完整的 URL 作为 referrer。
`origin-when-cross-origin`
指示浏览器发送完整的 URL 作为同源链接的 referrer,而只发送起源给跨源链接。
`same-origin`
指示浏览器发送完整的 URL,但只针对同源链接。对于跨源链接,将不发送 referrer。
`strict-origin`
指示浏览器只发送起源,而不是完整的 URL,并在协议降级时不发送 referrer。
`strict-origin-when-cross-origin`
当链接为同源且不发生协议降级时,指示浏览器发送完整的 URL;当链接为跨源且不发生协议降级时,只发送起源;当发生协议降级时,不发送 referrer。
`unsafe-url`
指示浏览器始终发送完整的 URL 作为 referrer。
未知政策值
当一个策略值被用户代理认为 [未知](<https://w3c.github.io/webappsec-referrer-policy/#unknown-policy-values>) 时,可以指定多个策略值以提供后备。最后一个被理解的指定值优先。为了支持这一点,可以在 [SECURE_REFERRER_POLICY](/read/django-5.1-zh/d165.md#std-setting-SECURE_REFERRER_POLICY) 中使用一个可迭代对象或逗号分隔的字符串。
#### 跨域开启策略
一些浏览器可以通过根据 [Cross-Origin Opener Policy](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy>) (COOP)标头的值将顶级窗口与其他文档隔离开来,将它们放入单独的浏览上下文组中。如果以这种方式隔离的文档打开一个跨源弹出窗口,弹出窗口的 `window.opener` 属性将为 `null`。使用 COOP 隔离窗口是一种深度防御,可有效防止跨源攻击,特别是像 Spectre 这样允许数据泄漏到共享浏览上下文中的攻击。
`SecurityMiddleware` 可以根据 [SECURE_CROSS_ORIGIN_OPENER_POLICY](/read/django-5.1-zh/d165.md#std-setting-SECURE_CROSS_ORIGIN_OPENER_POLICY) 设置为您设置 `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](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options>) 头。 如果 [SECURE_CONTENT_TYPE_NOSNIFF](/read/django-5.1-zh/d165.md#std-setting-SECURE_CONTENT_TYPE_NOSNIFF) 设置为 `True`,`SecurityMiddleware` 将对所有的响应进行这样的操作。
请注意,在大多数部署情况下,如果 Django 不涉及提供用户上传的文件,这个设置不会对您有所帮助。例如,如果您的 [MEDIA_URL](/read/django-5.1-zh/d165.md#std-setting-MEDIA_URL) 直接由您的前端 Web 服务器(nginx、Apache 等)提供服务,那么您需要在那里设置此标头。另一方面,如果您正在使用 Django 来执行某些操作,比如要求授权以下载文件,并且无法在 Web 服务器中设置标头,那么这个设置将会有用。
#### SSL 重定向
如果你的网站同时提供 HTTP 和 HTTPS 连接,大多数用户最终会默认使用不安全的连接。为了达到最佳的安全性,你应该将所有的 HTTP 连接重定向到 HTTPS。
如果你将 [SECURE_SSL_REDIRECT](/read/django-5.1-zh/d165.md#std-setting-SECURE_SSL_REDIRECT) 设置为 True,`SecurityMiddleware` 将永久(HTTP 301)重定向所有 HTTP 连接到 HTTPS。
备注
出于性能方面的考虑,最好在 Django 之外,在前端负载均衡器或反向代理服务器(如 [nginx](<https://nginx.org/>) )中做这些重定向。 [SECURE_SSL_REDIRECT](/read/django-5.1-zh/d165.md#std-setting-SECURE_SSL_REDIRECT) 是为了在部署情况下,这不是一个选项。
如果 [SECURE_SSL_HOST](/read/django-5.1-zh/d165.md#std-setting-SECURE_SSL_HOST) 设置有一个值,所有的重定向将被发送到该主机,而不是最初要求的主机。
如果你的网站上有几个页面应该通过 HTTP 提供,而不是重定向到 HTTPS,你可以在 [SECURE_REDIRECT_EXEMPT](/read/django-5.1-zh/d165.md#std-setting-SECURE_REDIRECT_EXEMPT) 设置中列出正则表达式来匹配这些 URL。
备注
如果你部署在负载均衡器或反向代理服务器后面,而 Django 似乎无法判断一个请求是否真的已经安全,你可能需要设置 [SECURE_PROXY_SSL_HEADER](/read/django-5.1-zh/d165.md#std-setting-SECURE_PROXY_SSL_HEADER) 配置。
### 会话中间件
_class_ `SessionMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/contrib/sessions/middleware.py#L12>)
启用会话支持。参见 [会话文档](/read/django-5.1-zh/d039.md)。
### 站点中间件
_class_ `CurrentSiteMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/contrib/sites/middleware.py#L6>)
将代表当前站点的 `site` 属性添加到每个传入的 `HttpRequest` 对象中。参见 [站点文档](/read/django-5.1-zh/d126.md#site-middleware)。
### 验证中间件
_class_ `AuthenticationMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/contrib/auth/middleware.py#L27>)
将 `user` 属性添加到每个传入的 `HttpRequest` 对象中,表示当前已登录的用户。请参阅 [Web 请求中的身份验证](<https://docs.djangoproject.com/zh-hans/5.1/topics/auth/default/#auth-web-requests>)。
_class_ `LoginRequiredMiddleware`[[源代码]](<https://github.com/django/django/blob/stable/5.1.x/django/contrib/auth/middleware.py#L41>)
New in Django 5.1.
Redirects all unauthenticated requests to a login page, except for views excluded with [login_not_required()](<https://docs.djangoproject.com/zh-hans/5.1/topics/auth/default/#django.contrib.auth.decorators.login_not_required> "django.contrib.auth.decorators.login_not_required"). The login page defaults to [settings.LOGIN_URL](/read/django-5.1-zh/d165.md#std-setting-LOGIN_URL), but can be customized.
Enable this middleware by adding it to the [MIDDLEWARE](/read/django-5.1-zh/d165.md#std-setting-MIDDLEWARE) setting **after** AuthenticationMiddleware:
MIDDLEWARE = [ "...", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.auth.middleware.LoginRequiredMiddleware", "...", ]
Make a view public, allowing unauthenticated requests, with [login_not_required()](<https://docs.djangoproject.com/zh-hans/5.1/topics/auth/default/#django.contrib.auth.decorators.login_not_required> "django.contrib.auth.decorators.login_not_required"). For example:
from django.contrib.auth.decorators import login_not_required
@login_not_required def contact_us(request): ...
Customize the login URL or field name for authenticated views with the [login_required()](<https://docs.djangoproject.com/zh-hans/5.1/topics/auth/default/#django.contrib.auth.decorators.login_required> "django.contrib.auth.decorators.login_required") decorator to set `login_url` or `redirect_field_name` respectively. For example:
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 ```
Ensure that your login view does not require a login.
To prevent infinite redirects, ensure you have enabled unauthenticated requests to your login view.
方法和属性
Subclass the middleware and override these to customize behavior for unauthenticated requests.
redirect_field_name
Defaults to "next".
get_login_url()
Returns the URL that unauthenticated requests will be redirected to. If defined, this returns the login_url set on the login_required() decorator. Defaults to settings.LOGIN_URL.
get_redirect_field_name()
Returns the name of the query parameter that contains the URL the user should be redirected to after a successful login. If defined, this returns the redirect_field_name set on the login_required() decorator. Defaults to redirect_field_name. If None is returned, a query parameter won’t be added.
class RemoteUserMiddleware[源代码]
用于利用 Web 服务器提供的身份验证的中间件。有关使用详细信息,请参阅 使用 REMOTE_USER 进行身份验证。
class PersistentRemoteUserMiddleware[源代码]
中间件用于在仅在登录页面启用时利用 Web 服务器提供的身份验证。有关使用详细信息,请参阅 仅在登录界面使用 REMOTE_USER。
CSRF 保护中间件
class CsrfViewMiddleware[源代码]
通过在 POST 表单中添加隐藏的表单字段,并检查请求的正确值,增加对跨站点伪造请求的保护。请参阅 跨站点伪造请求保护文档。
X-Frame-Options 中间件
class XFrameOptionsMiddleware[源代码]
简单的 通过 X-Frame-Options 头的点击劫持保护。
中间件顺序
下面是关于各种 Django 中间件类的排序的一些提示:
- SecurityMiddleware
如果你要开启 SSL 重定向,它应该排在列表的最前面,因为这样可以避免运行一堆其他不必要的中间件。
- UpdateCacheMiddleware
在修改 Vary 头(SessionMiddleware、GZipMiddleware、LocaleMiddleware)之前。
- GZipMiddleware
在任何可能改变或使用响应体的中间件之前。
在 UpdateCacheMiddleware 之后:修改 Vary 头。
- SessionMiddleware
在任何可能引发异常触发错误视图的中间件之前(如 PermissionDenied),如果你使用的是 CSRF_USE_SESSIONS。
在 UpdateCacheMiddleware 之后:修改 Vary 头。
- ConditionalGetMiddleware
在任何可能改变响应的中间件之前(它设置 ETag 头)。
在 GZipMiddleware 之后,这样它就不会在 gzip 压缩后的内容上计算 ETag 头。
- LocaleMiddleware
最上面的一个,仅次于 SessionMiddleware (使用会话数据)和 UpdateCacheMiddleware (修改 Vary 头)。
- CommonMiddleware
在任何可能改变响应的中间件之前(它设置 Content-Length 头)。出现在 CommonMiddleware 之前并改变响应的中间件必须重置 Content-Length。
靠近顶部:当 APPEND_SLASH 或 PREPEND_WWW 设置为 True 时,它会重定向。
在 SessionMiddleware 之后,如果你使用 CSRF_USE_SESSIONS。
- CsrfViewMiddleware
在任何假设 CSRF 攻击已经被处理的视图中间件之前。
在 RemoteUserMiddleware,或任何其他可能执行登录的认证中间件,从而旋转 CSRF 令牌,然后再向下调用中间件链。
在 SessionMiddleware 之后,如果你使用 CSRF_USE_SESSIONS。
- AuthenticationMiddleware
SessionMiddleware 之后:使用会话存储。
- LoginRequiredMiddleware
New in Django 5.1.
After AuthenticationMiddleware: uses user object.
- MessageMiddleware
SessionMiddleware 之后:可以使用基于会话的存储。
- FetchFromCacheMiddleware
在任何修改 Vary 头的中间件之后:该头用于为缓存哈希键选取一个值。
应该是接近底部,因为这是一种最后的中间件。
应该是接近底部,因为这是一种最后的中间件。
