中间件¶ T0>

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

可用的中间件

缓存中间件

UpdateCacheMiddleware[source]
FetchFromCacheMiddleware[source]

启用站点范围的缓存。 如果启用了这些功能,只要CACHE_MIDDLEWARE_SECONDS设置定义,每个Django驱动的页面将被缓存。 请参阅cache documentation

“通用”中间件

CommonMiddleware[source]

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

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

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

    如果APPEND_SLASHTrue,并且初始网址不以斜线结尾,并且在URLconf中找不到,则通过在结束。 如果在URLconf中找到这个新的URL,那么Django会将请求重定向到这个新的URL。 否则,像往常一样处理初始URL。

    For example, foo.com/bar will be redirected to foo.com/bar/ if you don’t have a valid URL pattern for foo.com/bar but do have a valid pattern for foo.com/bar/.

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

    这两个选项都是为了规范化URL。 哲学是每个URL应该存在于一个地方,而且只有一个地方。 从技术上来说,URL foo.com/bar不同于foo.com/bar/ - 搜索引擎索引器会将它们视为单独的URL--所以最好实践规范化网址。

  • 根据USE_ETAGS设置处理ETags。 如果USE_ETAGS设置为True,Django将通过MD5对页面内容进行散列来计算每个请求的ETag,然后它将负责发送不是 修改响应。

  • 为非流动响应设置Content-Length标题。

在Django 1.11中更改:

较早的版本没有设置Content-Length标题。

自1.11版以来已弃用: 不推荐使用USE_ETAGS设置,而是使用ConditionalGetMiddleware进行ETag处理。

CommonMiddleware。 response_redirect_class T0> ¶ T1>

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

BrokenLinkEmailsMiddleware[source]

异常中间件

ExceptionMiddleware T0> ¶ T1>

捕获请求/响应周期内发生的异常并返回相应的响应。

Django使用这个中间件,而不管你是否把它包含在MIDDLEWARE中,然而,如果你自己的中间件需要将这些异常转换成适当的响应,你可能需要子类。 LocaleMiddleware does this, for example.

GZip中间件

GZipMiddleware[source]

警告

Security researchers recently revealed that when compression techniques (including GZipMiddleware) are used on a website, the site may become exposed to a number of possible attacks. 在您的网站上使用GZipMiddleware之前,您应该仔细考虑是否受到这些攻击。 If you’re in any doubt about whether you’re affected, you should avoid using GZipMiddleware. 有关详情,请参阅BREACH论文(PDF)breachattack.com

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

这个中间件应该放在任何需要读或写响应体的中间件之前,以便压缩发生在之后。

如果以下任一情况属实,则不会压缩内容:

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

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

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

有条件的GET中间件

ConditionalGetMiddleware[source]

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

在Django 1.11中更改:

在较早的版本中,中间件设置Content-LengthDate标题,并且没有设置ETag标题。

区域设置中间件

LocaleMiddleware[source]

根据请求中的数据启用语言选择。 它为每个用户定制内容。 请参阅internationalization documentation

LocaleMiddleware。 response_redirect_class T0> ¶ T1>

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

消息中间件

MessageMiddleware[source]

启用基于cookie和会话的消息支持。 请参阅messages documentation

安全中间件

警告

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

SecurityMiddleware[source]

The django.middleware.security.SecurityMiddleware provides several security enhancements to the request/response cycle. 每个人都可以独立启用或禁用一个设置。

HTTP严格传输安全性

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

SecurityMiddleware will set this header for you on all HTTPS responses if you set the SECURE_HSTS_SECONDS setting to a non-zero integer value.

当启用HSTS时,首先使用一个小的值进行测试是个好主意,例如SECURE_HSTS_SECONDS = 3600 每当Web浏览器从您的站点看到HSTS标头时,就会拒绝在给定的时间段内与您的域进行非安全通信(使用HTTP)。 一旦您确认所有资产已在您的网站上安全使用(即HSTS没有任何损失),最好增加此值,以便不频繁的访问者受到保护(31536000秒,即1年)。

Additionally, if you set the SECURE_HSTS_INCLUDE_SUBDOMAINS setting to True, SecurityMiddleware will add the includeSubDomains directive to the Strict-Transport-Security header. 这是推荐的(假设所有的子域名都是使用HTTPS专门服务的),否则你的网站可能仍然是脆弱的,通过不安全的连接到一个子域名。

如果您希望将您的站点提交到浏览器预加载列表,请将SECURE_HSTS_PRELOAD设置为True preload指令附加到Strict-Transport-Security标头。

警告

HSTS策略适用于您的整个域,而不仅仅是您设置标题的响应的URL。 因此,如果仅通过HTTPS提供整个域,则应该只使用它。

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

注意

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

X-Content-Type的选项: nosniff

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

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

为了防止浏览器猜测内容类型并强制它始终使用Content-Type标题中提供的类型,可以传递X-Content-Type-Options:nosniff 标题。 SecurityMiddleware will do this for all responses if the SECURE_CONTENT_TYPE_NOSNIFF setting is True.

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

X-XSS-保护: 1; 模式=块

Some browsers have the ability to block content that appears to be an XSS attack. 他们通过在页面的GET或POST参数中查找JavaScript内容来工作。 如果JavaScript在服务器响应中重播,页面将被阻止呈现,并显示错误页面。

The X-XSS-Protection header is used to control the operation of the XSS filter.

要在浏览器中启用XSS过滤器,并强制它永远阻止可疑的XSS攻击,可以通过 X-XSS-保护: 1; 模式=块 头。 SecurityMiddleware will do this for all responses if the SECURE_BROWSER_XSS_FILTER setting is True.

警告

浏览器的XSS过滤器是一个有用的防御措施,但不能完全依赖。 它不能检测到所有的XSS攻击,并不是所有的浏览器都支持这个头文件。 Ensure you are still validating and sanitizing all input to prevent XSS attacks.

SSL重定向

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

If you set the SECURE_SSL_REDIRECT setting to True, SecurityMiddleware will permanently (HTTP 301) redirect all HTTP connections to HTTPS.

注意

出于性能原因,最好在Django之外,在前端负载均衡器或反向代理服务器(如nginx)中执行这些重定向。 SECURE_SSL_REDIRECT is intended for the deployment situations where this isn’t an option.

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

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

注意

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

会话中间件

SessionMiddleware[source]

启用会话支持。 请参阅session documentation

网站中间件

CurrentSiteMiddleware[source]

将表示当前站点的site属性添加到每个传入的HttpRequest对象。 请参阅sites documentation

认证中间件

AuthenticationMiddleware T0> ¶ T1>

将表示当前登录用户的user属性添加到每个传入的HttpRequest对象。 请参阅Authentication in Web requests

RemoteUserMiddleware T0> ¶ T1>

利用Web服务器提供的认证的中间件。 有关使用详情,请参阅Authentication using REMOTE_USER

PersistentRemoteUserMiddleware T0> ¶ T1>

仅在登录页面启用时使用Web服务器提供的身份验证的中间件。 请参阅Using REMOTE_USER on login pages only以获取使用详情。

CSRF保护中间件

CsrfViewMiddleware[source]

通过在POST表单中添加隐藏的表单字段并检查请求的正确值来添加对跨站点请求伪造的保护。 请参阅Cross Site Request Forgery protection documentation

X-Frame-Options中间件

XFrameOptionsMiddleware[source]

通过X-Frame-Options标题简单的clickjacking protection via the X-Frame-Options header

中间件排序

以下是关于各种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

    One of the topmost, after SessionMiddleware (uses session data) and UpdateCacheMiddleware (modifies Vary header).

  7. CommonMiddleware

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

    GZipMiddleware之后,所以它不会计算gzip内容上的ETag标题。

    Close to the top: it redirects when APPEND_SLASH or PREPEND_WWW are set to True.

  8. CsrfViewMiddleware

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

    如果您使用CSRF_USE_SESSIONS,它必须在SessionMiddleware之后。

  9. AuthenticationMiddleware

    After SessionMiddleware: uses session storage.

  10. MessageMiddleware

    After SessionMiddleware: can use session-based storage.

  11. FetchFromCacheMiddleware

    在任何修改Vary标头的中间件之后:该标头用于为缓存散列键选择一个值。

  12. FlatpageFallbackMiddleware

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

  13. RedirectFallbackMiddleware

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