中间件

    class UpdateCacheMiddleware

    class FetchFromCacheMiddleware

    启用全站缓存。如果启用了这些功能,那么每一个 Django 驱动的页面都会在 配置定义的时间内被缓存。参见 缓存文档

    “通用”中间件

    class CommonMiddleware

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

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

    • 根据 APPEND_SLASH 和 的配置进行 URL 重写。

      如果 APPEND_SLASHTrue,并且初始的 URL 没有以斜线结尾,而且在 URLconf 中也没有找到,那么就会在最后附加一个斜线形成一个新的 URL。如果在 URLconf 中找到了这个新的 URL,那么 Django 会将请求重定向到这个新的 URL。否则,初始的 URL 就会被照常处理。

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

      如果 为 True,缺乏前导“www. ”的 URL 将被重定向到带有前导“www. ”的同一 URL。

      这两个选项都是为了规范 URL。其理念是,每个 URL 应该存在于一个地方,而且只有一个地方。从技术上讲,URL foo.com/barfoo.com/bar/ 是不同的——搜索引擎索引器会将它们视为单独的 URL——所以最好的做法是将 URL 规范化。

      If necessary, individual views may be excluded from the APPEND_SLASH behavior using the no_append_slash() decorator:

      Changed in Django Development version:

      Support for the decorator was added.

    • 设置非流响应的 Content-Length 头。

    CommonMiddleware.``response_redirect_class

    默认为 HttpResponsePermanentRedirect。子类化 CommonMiddleware,并重写该属性来定制中间件发出的重定向。

    class BrokenLinkEmailsMiddleware

    • manager 发送失效链接通知邮件(参见 )。

    GZip 中间件

    class GZipMiddleware

    警告

    安全研究人员最近发现,当在网站上使用压缩技术(包括 GZipMiddleware)时,网站可能会受到一些可能的攻击。在你的网站上使用 GZipMiddleware 之前,你应该仔细考虑你是否会受到这些攻击。如果你对你是否受到影响有 任何 怀疑,你应该避免使用 GZipMiddleware。更多细节,请看 the BREACH paper (PDF) 和 。

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

    这个中间件应该放在任何其他需要读取或写入响应体的中间件之前,这样压缩就会在之后发生。

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

    • 内容主体长度小于 200 字节。
    • 响应已经设置了 Content-Encoding 头。
    • 请求(浏览器)没有发送包含 gzipAccept-Encoding 头。

    如果响应有 ETag 头,则 ETag 会变得很弱,以符合 RFC 7232#section-2.1

    你可以使用 装饰器对单个视图应用 GZip 压缩。

    条件 GET 中间件

    class ConditionalGetMiddleware

    处理有条件的 GET 操作。如果响应没有 ETag 头,中间件会根据需要添加一个。如果响应有 ETagLast-Modified 头,而请求有 If-None-MatchIf-Modified-Since,则响应被一个 HttpResponseNotModified 替换。

    class LocaleMiddleware

    可以根据请求的数据选择语言。它为每个用户定制内容。请参阅 。

    LocaleMiddleware.``response_redirect_class

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

    消息中间件

    class MessageMiddleware

    启用基于 cookie 和会话的消息支持。参见 。

    安全中间件

    警告

    如果你的部署情况允许,通常让你的前端 Web 服务器执行“安全中间件”提供的功能是个好主意。这样一来,如果有一些请求不是由 Django 服务的(比如静态资源或用户上传的文件),它们将和对你的 Django 应用的请求有同样的保护。

    class SecurityMiddleware

    django.middleware.security.SecurityMiddleware 为请求/响应周期提供了若干安全增强功能。每一项都可以通过设置独立地启用或禁用。

    HTTP 严格传输安全

    对于只能通过 HTTPS 访问的网站,你可以通过设置 来指示现代浏览器拒绝通过不安全的连接连接到你的域名(在给定的时间内)。这可以减少你受到一些 SSL 剥离中间人(MITM)的攻击。

    如果你将 SECURE_HSTS_SECONDS 设置为一个非零的整数值,SecurityMiddleware 将为你在所有 HTTPS 响应中设置这个头。

    当启用 HSTS 时,最好先使用一个小值进行测试,例如 为一小时。每次 Web 浏览器看到你的网站的 HSTS 头时,它将在给定的时间内拒绝与你的域名进行非安全通信(使用 HTTP)。一旦你确认你的网站上所有的资产都是安全服务的(即 HSTS 没有破坏任何东西),最好是增加这个值,这样不经常访问的人就会受到保护(31536000秒,即 1 年,是常见的)。

    此外,如果你将 SECURE_HSTS_INCLUDE_SUBDOMAINS 设置为 TrueSecurityMiddleware 将在 Strict-Transport-Security 头中添加 includeSubDomains 指令。建议这样做(假设所有的子域都只使用 HTTPS 服务),否则你的网站仍然可能通过不安全的连接到子域而受到攻击。

    如果你希望将你的网站提交到 ,请将 SECURE_HSTS_PRELOAD 设置为 True。这样就会把 preload 指令附加到 Strict-Transport-Security 头。

    警告

    HSTS 策略适用于你的整个域,而不仅仅是你设置响应头的 URL。因此,你应该只在你的整个域名只通过 HTTPS 服务时使用它。

    注解

    如果你部署在负载平衡器或反向代理服务器后面,而 Strict-Transport-Security 头没有被添加到你的响应中,这可能是因为 Django 没有意识到它是在一个安全的连接上;你可能需要设置 设置。

    Referrer 政策

    浏览器使用 referer 头 作为向网站发送关于用户如何到达那里的信息的一种方式。当用户点击一个链接时,浏览器将发送链接页面的完整 URL 作为 referrer。虽然这对某些目的来说可能很有用——例如查明谁在链接到你的网站——但它也可能引起隐私问题,因为它告诉一个网站,一个用户正在访问另一个网站。

    一些浏览器能够接受关于是否应该在用户点击链接时发送 HTTP Referer 头的提示;这种提示通过 提供。这个头可以向浏览器建议三种行为中的任何一种:

    • 仅起源:只发送 referrer 中的“起源”。起源由方案、主机和(可选)端口号组成。例如,如果用户访问的是 https://example.com/page.html,起源就是 https://example.com/
    • 无 referrer:完全不发送 Referer 头。

    有两种类型的情况,这个头可以告诉浏览器要注意:

    • 同源与跨源:从 https://example.com/1.htmlhttps://example.com/2.html 的链接为同源链接。从 https://example.com/page.htmlhttps://not.example.com/page.html 的链接为跨源链接。
    • 协议降级:如果包含链接的页面是通过 HTTPS 服务的,但被链接的页面不是通过 HTTPS 服务的,就会发生降级。

    警告

    当你的网站通过 HTTPS 提供服务时, Django 的 CSRF 保护系统 需要 Referer 头存在,所以完全禁用 Referer 头会干扰 CSRF 保护。要想在保留 CSRF 保护的同时,获得禁用 Referer 头的大部分好处,可以考虑只启用同源引用。

    SecurityMiddleware 可以根据 设置,为你设置 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。

    未知政策值

    当一个策略值被用户代理认为 未知 时,可以指定多个策略值以提供后备。最后一个被理解的指定值优先。为了支持这一点,可以在 中使用一个可迭代对象或逗号分隔的字符串。

    X-Content-Type-Options: nosniff

    一些浏览器会试图猜测它们获取的资源的内容类型,覆盖 Content-Type 头。虽然这可以帮助显示配置不当的服务器的网站,但也会带来安全风险。

    如果你的网站提供用户上传的文件,恶意用户可能会上传一个特制的文件,当你认为它是无害的东西时,该文件会被浏览器解释为 HTML 或 JavaScript。

    为了防止浏览器猜测内容类型,并迫使它总是使用 Content-Type 头中提供的类型,你可以传递 X-Content-Type-Options: nosniff 头。 如果 设置为 TrueSecurityMiddleware 将对所有的响应进行这样的操作。

    需要注意的是,在大多数部署情况下,Django 并不参与服务用户上传的文件,这个设置对你没有帮助。例如,如果你的 MEDIA_URL 是由你的前端 Web 服务器(nginx,Apache等)直接提供服务的,那么你会希望在那里设置这个头。另一方面,如果你使用 Django 来做一些事情,比如需要授权才能下载文件,而你又不能用你的 Web 服务器来设置头,那么这个设置就会很有用。

    X-XSS-Protection: 1; mode=block

    一些浏览器有能力阻止看起来是 的内容。它们的工作原理是在页面的 GET 或 POST 参数中寻找 JavaScript 内容。如果 JavaScript 在服务器的响应中被重放,页面就会被阻止渲染,并显示一个错误页面。

    X-XSS-Protection 头 用于控制 XSS 过滤器的操作。

    要在浏览器中启用 XSS 过滤器,并强制其始终阻止可疑的 XSS 攻击,你可以通过 X-XSS-Protection: 1; mode=block 头。如果 设置为 TrueSecurityMiddleware 将对所有响应进行此操作。

    警告

    浏览器 XSS 过滤器是一种有用的防御措施,但不能完全依赖它。它不能检测所有的 XSS 攻击,而且不是所有的浏览器都支持头。确保你仍然 验证和消毒 所有输入,以防止 XSS 攻击。

    SSL 重定向

    如果你的网站同时提供 HTTP 和 HTTPS 连接,大多数用户最终会默认使用不安全的连接。为了达到最佳的安全性,你应该将所有的 HTTP 连接重定向到 HTTPS。

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

    注解

    出于性能方面的考虑,最好在 Django 之外,在前端负载均衡器或反向代理服务器(如 nginx )中做这些重定向。 是为了在部署情况下,这不是一个选项。

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

    如果你的网站上有几个页面应该通过 HTTP 提供,而不是重定向到 HTTPS,你可以在 设置中列出正则表达式来匹配这些 URL。

    注解

    如果你部署在负载均衡器或反向代理服务器后面,而 Django 似乎无法判断一个请求是否真的已经安全,你可能需要设置 SECURE_PROXY_SSL_HEADER 配置。

    会话中间件

    class SessionMiddleware

    启用会话支持。参见 。

    将代表当前站点的 site 属性添加到每个传入的 HttpRequest 对象中。参见 站点文档

    验证中间件

    class AuthenticationMiddleware

    将代表当前登录的用户的 user 属性添加到每个传入的 HttpRequest 对象中。见 。

    class RemoteUserMiddleware

    用于利用 Web 服务器提供的认证的中间件。详细使用方法请看 使用 REMOTE_USER 进行身份验证

    class PersistentRemoteUserMiddleware

    当仅在登录页面启用时,利用 Web 服务器提供的认证的中间件。详细使用方法参见 。

    CSRF 保护中间件

    class CsrfViewMiddleware

    通过在 POST 表单中添加隐藏的表单字段,并检查请求的正确值,增加对跨站点伪造请求的保护。请参阅 跨站点伪造请求保护文档

    X-Frame-Options 中间件

    class XFrameOptionsMiddleware

    简单的 。

    中间件顺序

    下面是关于各种 Django 中间件类的排序的一些提示:

    1. SecurityMiddleware

      如果你要开启 SSL 重定向,它应该排在列表的最前面,因为这样可以避免运行一堆其他不必要的中间件。

    2. 在修改 Vary 头(SessionMiddlewareGZipMiddlewareLocaleMiddleware)之前。

    3. GZipMiddleware

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

      UpdateCacheMiddleware 之后:修改 Vary 头。

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

      UpdateCacheMiddleware 之后:修改 Vary 头。

    5. ConditionalGetMiddleware

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

      GZipMiddleware 之后,这样它就不会在 gzip 压缩后的内容上计算 ETag 头。

    6. 最上面的一个,仅次于 SessionMiddleware (使用会话数据)和 UpdateCacheMiddleware (修改 Vary 头)。

    7. CommonMiddleware

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

      靠近顶部:当 或 PREPEND_WWW 设置为 True 时,它会重定向。

      SessionMiddleware 之后,如果你使用 。

    8. CsrfViewMiddleware

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

      在 ,或任何其他可能执行登录的认证中间件,从而旋转 CSRF 令牌,然后再向下调用中间件链。

      SessionMiddleware 之后,如果你使用 CSRF_USE_SESSIONS

    9. SessionMiddleware 之后:使用会话存储。

    10. MessageMiddleware

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

    11. 在任何修改 Vary 头的中间件之后:该头用于为缓存哈希键选取一个值。

    12. FlatpageFallbackMiddleware

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

    13. 应该是接近底部,因为这是一种最后的中间件。