Skip to main content

中间件

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

可用中间件

缓存中间件

class UpdateCacheMiddleware
class FetchFromCacheMiddleware

启用站点级缓存。如果启用这些功能,每个Django供电页面将被缓存,只要 CACHE_MIDDLEWARE_SECONDS 设置定义。见 缓存文档

“普通”中间件

class CommonMiddleware[源代码]

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

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

  • 根据 APPEND_SLASHPREPEND_WWW 设置执行URL重写。

    如果 APPEND_SLASHTrue,并且初始URL不以斜杠结尾,并且在URLconf中找不到,则通过在末尾添加斜杠形成新的URL。如果在URLconf中找到这个新的URL,Django会将请求重定向到这个新的URL。否则,将照常处理初始URL。

    例如,如果您没有针对 foo.com/bar 的有效网址格式,但 dofoo.com/bar/ 有有效的格式,则 foo.com/bar 将重定向到 foo.com/bar/

    如果 PREPEND_WWWTrue,则缺少前导“www”的网址。将被重定向到具有领先“www”的相同URL。

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

  • 根据 USE_ETAGS 设置处理ETag。如果 USE_ETAGS 设置为 True,Django将为MD5计算每个请求的ETag - 散列页面内容,如果适当,它将负责发送 Not Modified 响应。

CommonMiddleware.response_redirect_class

默认为 HttpResponsePermanentRedirect。子类 CommonMiddleware 并覆盖该属性以自定义中间件发出的重定向。

class BrokenLinkEmailsMiddleware[源代码]

异常中间件

class ExceptionMiddleware
New in Django 1.10.

捕获在请求/响应周期中引发的异常并返回适当的响应。

Django使用这个中间件,不管你是否将它包含在 MIDDLEWARE 中,但是,如果你自己的中间件需要将这些异常转换为适当的响应,你可能想要子类化。 LocaleMiddleware 这样做,例如。

GZip中间件

class GZipMiddleware

警告

安全研究人员最近透露,当在网站上使用压缩技术(包括 GZipMiddleware)时,网站可能会暴露于多种可能的攻击。在您的网站上使用 GZipMiddleware 之前,您应该非常仔细地考虑是否受到这些攻击。如果你在 any 怀疑你是否受到影响,你应该避免使用 GZipMiddleware。有关更多详细信息,请参阅 the BREACH paper (PDF)breachattack.com

压缩了解GZip压缩(所有现代浏览器)的浏览器的内容。

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

如果满足以下任一条件,它不会压缩内容:

  • 内容主体的长度小于200字节。

  • 响应已设置 Content-Encoding 头。

  • 请求(浏览器)尚未发送包含 gzipAccept-Encoding 头。

您可以使用 gzip_page() 装饰器将GZip压缩应用于单个视图。

Changed in Django 1.10:

在旧版本中,Django的CSRF保护机制在使用压缩时容易受到BREACH攻击。这不再是这样,但你仍然应该小心不要以这种方式妥协你自己的秘密。

条件GET中间件

class ConditionalGetMiddleware[源代码]

处理条件GET操作。如果响应具有 ETagLast-Modified 报头,并且请求具有 If-None-MatchIf-Modified-Since,则响应由 HttpResponseNotModified 替换。

还设置 DateContent-Length 响应标头。

语言环境中间件

class LocaleMiddleware

根据请求中的数据启用语言选择。它为每个用户定制内容。见 国际化文档

LocaleMiddleware.response_redirect_class

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

消息中间件

class MessageMiddleware[源代码]

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

安全中间件

警告

如果部署情况允许,通常最好让前端Web服务器执行 SecurityMiddleware 提供的功能。这样,如果有一些请求不是由Django提供的(例如静态媒体或用户上传的文件),他们将有与您的Django应用程序的请求相同的保护。

class SecurityMiddleware[源代码]

django.middleware.security.SecurityMiddleware 对请求/响应周期提供若干安全增强。每个都可以通过设置独立启用或禁用。

HTTP严格传输安全

对于只应通过HTTPS访问的网站,您可以通过设置 “Strict-Transport-Security” header 指示现代浏览器通过不安全的连接(在给定时间段内)拒绝连接到您的域名。这减少了您暴露于一些SSL剥离中间人(MITM)攻击。

如果将 SECURE_HSTS_SECONDS 设置为非零整数值,则 SecurityMiddleware 将在所有HTTPS响应中为您设置此标头。

当启用HSTS时,最好先使用一个小值进行测试,例如,SECURE_HSTS_SECONDS = 3600 一个小时。每当Web浏览器从您的网站查看HSTS标头时,它将拒绝在给定时间内与您的域非安全(使用HTTP)通信。一旦您确认所有资产安全地在您的网站上投放(即HSTS没有破坏任何东西),最好增加此值,以便不常访问者受到保护(31536000秒,即1年,很常见)。

此外,如果将 SECURE_HSTS_INCLUDE_SUBDOMAINS 设置设置为 TrueSecurityMiddleware 将向 Strict-Transport-Security 头添加 includeSubDomains 伪指令。建议这样做(假设所有子域都是使用HTTPS独家提供的),否则您的网站可能仍然通过与子域的不安全连接而受到攻击。

警告

HSTS策略适用于整个域,而不仅仅是您设置标头的响应的网址。因此,如果您的整个域仅通过HTTPS投放,您应该只使用它。

正确尊重HSTS标题的浏览器将拒绝允许用户绕过警告并连接到具有过期,自签名或无效的SSL证书的站点。如果您使用HSTS,请确保您的证书是良好的形状,并保持这种方式!

注解

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

X-Content-Type-Options: nosniff

某些浏览器会尝试猜测他们获取的资产的内容类型,覆盖 Content-Type 标题。虽然这可以帮助显示网站配置不正确的服务器,但它也可能带来安全风险。

如果您的网站提供用户上传的文件,恶意用户可能会上传一个特制的文件,当您期望它是无害的时,浏览器会将其解释为HTML或JavaScript。

要了解有关此标题和浏览器如何处理的更多信息,您可以在 IE Security Blog 上阅读。

为了防止浏览器猜测内容类型并强制它始终使用 Content-Type 头中提供的类型,您可以传递 X-Content-Type-Options: nosniff 头。如果 SECURE_CONTENT_TYPE_NOSNIFF 设置为 TrueSecurityMiddleware 将对所有响应执行此操作。

请注意,在大多数部署情况下,Django不参与提供用户上传的文件,此设置不会帮助您。例如,如果您的 MEDIA_URL 由您的前端Web服务器(nginx,Apache等)直接提供,那么您想要设置此标题。另一方面,如果您使用Django执行某些操作,例如需要授权才能下载文件,并且您无法使用Web服务器设置标题,则此设置将很有用。

X-XSS-Protection: 1; mode=block

某些浏览器能够阻止看起来像 XSS attack 的内容。它们通过在页面的GET或POST参数中查找JavaScript内容来工作。如果JavaScript在服务器的响应中重播,则会阻止该页面呈现,并显示错误页面。

X-XSS-Protection header 用于控制XSS滤波器的操作。

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

警告

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

SSL重定向

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

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

注解

出于性能原因,最好在前端负载均衡器或反向代理服务器(如 nginx)中在Django之外执行这些重定向。 SECURE_SSL_REDIRECT 旨在用于不是选项的部署情况。

如果 SECURE_SSL_HOST 设置具有值,则所有重定向都将发送到该主机,而不是原始请求的主机。

如果您的网站上有几个网页应通过HTTP提供,而不是重定向到HTTPS,则可以列出正则表达式以匹配 SECURE_REDIRECT_EXEMPT 设置中的网址。

注解

如果您部署在负载平衡器或反向代理服务器后面,并且Django似乎无法判断请求实际上是否已经安全,您可能需要设置 SECURE_PROXY_SSL_HEADER 设置。

会话中间件

class SessionMiddleware

启用会话支持。见 会话文档

网站中间件

class CurrentSiteMiddleware[源代码]

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

认证中间件

class AuthenticationMiddleware

将表示当前登录的用户的 user 属性添加到每个传入的 HttpRequest 对象。参见 Web请求中的身份验证

class RemoteUserMiddleware

使用Web服务器提供的身份验证的中间件。有关使用详细信息,请参阅 使用 REMOTE_USER 的验证

class PersistentRemoteUserMiddleware
New in Django 1.9.

用于仅在登录页面上启用Web服务器提供的身份验证的中间件。有关使用详细信息,请参阅 仅在登录页面上使用 REMOTE_USER

CSRF保护中间件

class CsrfViewMiddleware

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

X-Frame-Options 中间件

class XFrameOptionsMiddleware[源代码]

简单 点击防护通过X-Frame-Options标题

中间件排序

这里有一些关于各种Django中间件类的顺序的提示:

  1. SecurityMiddleware

    如果你要打开SSL重定向,避免运行一堆其他不必要的中间件,它应该靠近列表的顶部。

  2. UpdateCacheMiddleware

    之前修改 Vary 头(SessionMiddlewareGZipMiddlewareLocaleMiddleware)。

  3. GZipMiddleware

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

    UpdateCacheMiddleware 后:修改 Vary 头。

  4. ConditionalGetMiddleware

    CommonMiddleware 之前:当 USE_ETAGS = True 时使用其 ETag 报头。

  5. SessionMiddleware

    UpdateCacheMiddleware 后:修改 Vary 头。

  6. LocaleMiddleware

    SessionMiddleware (使用会话数据)和 UpdateCacheMiddleware (修改 Vary 头)之后的最顶层之一。

  7. CommonMiddleware

    在任何中间件可能改变响应之前(它计算 ETags)。

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

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

  8. CsrfViewMiddleware

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

  9. AuthenticationMiddleware

    SessionMiddleware 后:使用会话存储。

  10. MessageMiddleware

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

  11. FetchFromCacheMiddleware

    在修改 Vary 头部的任何中间件之后:该头部用于为高速缓存哈希键选择值。

  12. FlatpageFallbackMiddleware

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

  13. RedirectFallbackMiddleware

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