中间件

本文档解释了Django附带的所有中间件组件。有关如何使用它们以及如何编写自己的中间件的信息,请参见 middleware usage guide .

可用中间件

缓存中间件

class UpdateCacheMiddleware[源代码]
class FetchFromCacheMiddleware[源代码]

启用站点范围的缓存。如果启用了这些,则只要 CACHE_MIDDLEWARE_SECONDS 设置定义。见 cache documentation .

“通用”中间件

class CommonMiddleware[源代码]

为完美主义者增加了一些便利:

  • 禁止访问中的用户代理 DISALLOWED_USER_AGENTS 设置,它应该是已编译正则表达式对象的列表。

  • 基于执行URL重写 APPEND_SLASHPREPEND_WWW 设置。

    如果 APPEND_SLASHTrue 初始URL没有以斜杠结尾,并且在urlconf中找不到它,然后在末尾附加斜杠来形成新的URL。如果在urlconf中找到这个新的url,那么django会将请求重定向到这个新的url。否则,初始URL会像往常一样被处理。

    例如, foo.com/bar 将被重定向到 foo.com/bar/ 如果没有有效的URL模式 foo.com/bar 但是 do 具有有效的模式 foo.com/bar/ .

    如果 PREPEND_WWWTrue ,缺少前导“www.”的URL将被重定向到具有前导“www”的同一URL。

    这两个选项都是为了规范化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

这个 django.middleware.gzip.GZipMiddleware 为理解GZip压缩的浏览器(所有现代浏览器)压缩内容。

这个中间件应该放在任何其他需要读取或写入响应体的中间件之前,以便随后进行压缩。

如果以下任何一项为真,则不会压缩内容:

  • 内容正文的长度小于200字节。

  • 响应已设置 Content-Encoding 标题。

  • 请求(浏览器)未发送 Accept-Encoding 包含标题 gzip .

如果响应具有 ETag 标头,则ETag被设置为弱以符合 RFC 9110#section-8.8.1

您可以使用 gzip_page() 装饰符。

条件获取中间件

class ConditionalGetMiddleware[源代码]

处理条件获取操作。如果响应没有 ETag 头,如果需要,中间件会添加一个。如果响应有 ETagLast-Modified 头,请求 If-None-MatchIf-Modified-Since ,响应被替换为 HttpResponseNotModified .

本地中间件

class LocaleMiddleware[源代码]

基于请求中的数据启用语言选择。它为每个用户定制内容。见 internationalization documentation .

LocaleMiddleware.response_redirect_class

默认为 HttpResponseRedirect . 子类 LocaleMiddleware 并重写该属性以自定义中间件发出的重定向。

消息中间件

class MessageMiddleware[源代码]

启用基于cookie和会话的消息支持。见 messages documentation .

安全中间件

警告

如果您的部署情况允许,让前端Web服务器执行由 SecurityMiddleware 。这样,如果有Django没有处理的请求(例如静态媒体或用户上传的文件),它们将得到与对Django应用程序的请求相同的保护。

class SecurityMiddleware[源代码]

这个 django.middleware.security.SecurityMiddleware 为请求/响应周期提供了几个安全增强。每个都可以通过一个设置单独启用或禁用。

HTTP严格传输安全

对于只能通过https访问的站点,可以通过设置 `"Strict-Transport-Security" header`_ _. 这减少了您对SSL剥离中间人(MITM)攻击的暴露。

SecurityMiddleware 如果设置 SECURE_HSTS_SECONDS 设置为非零整数值。

启用HSTS时,最好首先使用较小的值进行测试,例如, SECURE_HSTS_SECONDS = 3600 一小时。Web浏览器每次从您的站点看到HSTS标头时,都会拒绝在给定时间段内以非安全方式(使用HTTP)与您的域进行通信。一旦您确认所有资产都在您的站点上安全地提供服务(即HSTS没有损坏任何东西),最好增加此值,以便保护不经常访问的访问者(通常为31536000秒,即1年)。

此外,如果设置 SECURE_HSTS_INCLUDE_SUBDOMAINS 设置为 TrueSecurityMiddleware 将添加 includeSubDomains 指示 Strict-Transport-Security 标题。建议这样做(假设所有子域都是以https的方式提供服务的),否则您的站点仍然可能由于与子域的不安全连接而受到攻击。

如果您希望将站点提交到 browser preload list 设置 SECURE_HSTS_PRELOAD 设置为 True . 它附加了 preload 指示 Strict-Transport-Security 标题。

警告

HSTS策略适用于整个域,而不仅仅是设置头的响应的URL。因此,仅当整个域仅通过HTTPS提供服务时才应使用它。

正确遵守hsts头的浏览器将拒绝允许用户绕过警告并连接到具有过期、自签名或其他无效SSL证书的站点。如果您使用HST,请确保您的证书状态良好,并保持这种状态!

备注

如果部署在负载均衡器或反向代理服务器之后,并且 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 , the Referer 标题将包含 "https://example.com/page.html" .

  • 仅来源:只发送“来源”在推荐人。源代码由方案、主机和(可选)端口号组成。例如,如果用户正在访问 https://example.com/page.html ,应该是 https://example.com/ .

  • 无推荐人:不发送 Referer 完全是头。

此标题可以告诉浏览器要注意的两种情况:

  • 同源与交叉:来自 https://example.com/1.htmlhttps://example.com/2.html 是同一个起源。链接来自 https://example.com/page.htmlhttps://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,并在协议降级发生时不发送referer。

strict-origin-when-cross-origin

指示浏览器在链接相同且未发生协议降级的情况下发送完整的URL;当链接跨源且未发生协议降级时,仅发送源站;当发生协议降级时,不发送引用。

unsafe-url

指示浏览器始终将完整的URL作为引用发送。

未知策略值

其中策略值为 `unknown`_ _通过用户代理,可以指定多个策略值来提供回退。最后一个被理解的指定值优先。为了支持这一点,iterable或逗号分隔的字符串可以与 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的文档或通过设置 unsafe-none

unsafe-none

允许将文档添加到其打开者的浏览上下文组中,除非打开者本身具有 same-originsame-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 由您的前端Web服务器(nginx、apache等)直接提供服务然后,您会想要在那里设置这个标题。另一方面,如果您正在使用Django执行诸如需要授权才能下载文件之类的操作,并且无法使用您的Web服务器设置头文件,则此设置将非常有用。

SSL重定向

如果您的站点同时提供HTTP和HTTPS连接,那么默认情况下,大多数用户最终都会得到一个不安全的连接。为了获得最佳安全性,您应该将所有HTTP连接重定向到HTTPS。

如果你设置 SECURE_SSL_REDIRECT 设置为真, SecurityMiddleware 将永久(HTTP 301)重定向所有HTTP连接到HTTPS。

备注

出于性能原因,最好在Django之外、前端负载均衡器或反向代理服务器(如 nginx . SECURE_SSL_REDIRECT 用于不可选择的部署情况。

如果 SECURE_SSL_HOST 设置有一个值,所有重定向都将发送到该主机,而不是最初请求的主机。

如果您的站点上有几个页面应该可以通过HTTP访问,而不是重定向到HTTPS,则可以列出正则表达式以匹配 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

用于利用Web服务器提供的身份验证的中间件。看见 如何使用进行身份验证 REMOTE_USER 了解用法详细信息。

class PersistentRemoteUserMiddleware

当仅在登录页面上启用时,用于利用Web服务器提供的身份验证的中间件。看见 使用 REMOTE_USER 仅在登录页上 了解用法详细信息。

CSRF保护中间件

class CsrfViewMiddleware[源代码]

通过将隐藏的表单字段添加到发布表单并检查请求的正确值,添加对跨站点请求伪造的保护。见 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 页眉 (SessionMiddlewareGZipMiddlewareLocaleMiddleware

  3. GZipMiddleware

    在任何可能更改或使用响应主体的中间件之前。

    UpdateCacheMiddleware 修改 Vary 标题。

  4. SessionMiddleware

    在任何可能引发异常以触发错误视图的中间件之前(例如 PermissionDenied )如果你在使用 CSRF_USE_SESSIONS .

    UpdateCacheMiddleware 修改 Vary 标题。

  5. ConditionalGetMiddleware

    在任何可能更改响应的中间件之前(它设置 ETag 标题)。

    GZipMiddleware 所以它不能计算 ETag gzip内容的标题。

  6. LocaleMiddleware

    最上面的一个,之后 SessionMiddleware (使用会话数据)和 UpdateCacheMiddleware (修改 Vary 标题)。

  7. CommonMiddleware

    在任何可能更改响应的中间件之前(它设置 Content-Length 标题)。以前出现的中间件 CommonMiddleware 并更改响应必须重置 Content-Length .

    接近顶部:当 APPEND_SLASHPREPEND_WWW 设置为 True .

    SessionMiddleware 如果你在用 CSRF_USE_SESSIONS .

  8. CsrfViewMiddleware

    在任何假设已经处理了CSRF攻击的视图中间件之前。

    之前 RemoteUserMiddleware ,或任何其他身份验证中间件,它们可能执行登录,从而在调用中间件链之前轮换CSRF令牌。

    SessionMiddleware 如果你在用 CSRF_USE_SESSIONS .

  9. AuthenticationMiddleware

    SessionMiddleware :使用会话存储。

  10. MessageMiddleware

    SessionMiddleware :可以使用基于会话的存储。

  11. FetchFromCacheMiddleware

    在任何修改 Vary header:这个header用于为缓存哈希键选择一个值。

  12. FlatpageFallbackMiddleware

    应该接近底部,因为它是中间件的最后一种手段。

  13. RedirectFallbackMiddleware

    应该接近底部,因为它是中间件的最后一种手段。