中间件¶
本文档解释了Django附带的所有中间件组件。有关如何使用它们以及如何编写自己的中间件的信息,请参阅 中间件使用指南。
可用中间件¶
缓存中间件¶
-
class
UpdateCacheMiddleware
¶
-
class
FetchFromCacheMiddleware
¶
启用站点级缓存。如果启用这些功能,每个Django供电页面将被缓存,只要 CACHE_MIDDLEWARE_SECONDS
设置定义。见 缓存文档。
“普通”中间件¶
为完美主义者添加一些便利:
禁止在
DISALLOWED_USER_AGENTS
设置中访问用户代理,这应该是已编译的正则表达式对象的列表。根据
APPEND_SLASH
和PREPEND_WWW
设置执行URL重写。如果
APPEND_SLASH
是True
,并且初始URL不以斜杠结尾,并且在URLconf中找不到,则通过在末尾添加斜杠形成新的URL。如果在URLconf中找到这个新的URL,Django会将请求重定向到这个新的URL。否则,将照常处理初始URL。例如,如果您没有针对
foo.com/bar
的有效网址格式,但 do 对foo.com/bar/
有有效的格式,则foo.com/bar
将重定向到foo.com/bar/
。如果
PREPEND_WWW
是True
,则缺少前导“www”的网址。将被重定向到具有领先“www”的相同URL。这两个选项都是为了规范化URL。理念是每个URL应该存在于一个,而且只有一个地方。技术上来说,URL
foo.com/bar
与foo.com/bar/
不同 - 搜索引擎索引器会将它们视为单独的URL,因此最佳做法是规范化URL。根据
USE_ETAGS
设置处理ETag。如果USE_ETAGS
设置为True
,Django将为MD5计算每个请求的ETag - 散列页面内容,如果适当,它将负责发送Not Modified
响应。
-
CommonMiddleware.
response_redirect_class
¶
默认为 HttpResponsePermanentRedirect
。子类 CommonMiddleware
并覆盖该属性以自定义中间件发出的重定向。
异常中间件¶
-
class
ExceptionMiddleware
¶
捕获在请求/响应周期中引发的异常并返回适当的响应。
Http404
由handler404
处理(或者如果DEBUG=True
是更友好的调试页面)。PermissionDenied
由handler403
处理。MultiPartParserError
由handler400
处理。SuspiciousOperation
由handler400
处理(或者如果DEBUG=True
是更友好的调试页面)。任何其他异常由
handler500
处理(或者如果DEBUG=True
是更友好的调试页面)。
Django使用这个中间件,不管你是否将它包含在 MIDDLEWARE
中,但是,如果你自己的中间件需要将这些异常转换为适当的响应,你可能想要子类化。 LocaleMiddleware
这样做,例如。
GZip中间件¶
-
class
GZipMiddleware
¶
警告
安全研究人员最近透露,当在网站上使用压缩技术(包括 GZipMiddleware
)时,网站可能会暴露于多种可能的攻击。在您的网站上使用 GZipMiddleware
之前,您应该非常仔细地考虑是否受到这些攻击。如果你在 any 怀疑你是否受到影响,你应该避免使用 GZipMiddleware
。有关更多详细信息,请参阅 the BREACH paper (PDF) 和 breachattack.com。
压缩了解GZip压缩(所有现代浏览器)的浏览器的内容。
此中间件应放置在任何其他需要读取或写入响应主体的中间件之前,以便之后进行压缩。
如果满足以下任一条件,它不会压缩内容:
内容主体的长度小于200字节。
响应已设置
Content-Encoding
头。请求(浏览器)尚未发送包含
gzip
的Accept-Encoding
头。
您可以使用 gzip_page()
装饰器将GZip压缩应用于单个视图。
在旧版本中,Django的CSRF保护机制在使用压缩时容易受到BREACH攻击。这不再是这样,但你仍然应该小心不要以这种方式妥协你自己的秘密。
条件GET中间件¶
处理条件GET操作。如果响应具有 ETag
或 Last-Modified
报头,并且请求具有 If-None-Match
或 If-Modified-Since
,则响应由 HttpResponseNotModified
替换。
还设置 Date
和 Content-Length
响应标头。
语言环境中间件¶
-
class
LocaleMiddleware
¶
根据请求中的数据启用语言选择。它为每个用户定制内容。见 国际化文档。
-
LocaleMiddleware.
response_redirect_class
¶
默认为 HttpResponseRedirect
。子类 LocaleMiddleware
并覆盖该属性以自定义中间件发出的重定向。
安全中间件¶
警告
如果部署情况允许,通常最好让前端Web服务器执行 SecurityMiddleware
提供的功能。这样,如果有一些请求不是由Django提供的(例如静态媒体或用户上传的文件),他们将有与您的Django应用程序的请求相同的保护。
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
设置设置为 True
,SecurityMiddleware
将向 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
设置为 True
,SecurityMiddleware
将对所有响应执行此操作。
请注意,在大多数部署情况下,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
设置为 True
,SecurityMiddleware
将对所有响应执行此操作。
警告
浏览器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
AuthenticationMiddleware
¶
将表示当前登录的用户的 user
属性添加到每个传入的 HttpRequest
对象。参见 Web请求中的身份验证。
-
class
RemoteUserMiddleware
¶
使用Web服务器提供的身份验证的中间件。有关使用详细信息,请参阅 使用 REMOTE_USER 的验证。
-
class
PersistentRemoteUserMiddleware
¶
用于仅在登录页面上启用Web服务器提供的身份验证的中间件。有关使用详细信息,请参阅 仅在登录页面上使用 REMOTE_USER。
中间件排序¶
这里有一些关于各种Django中间件类的顺序的提示:
-
如果你要打开SSL重定向,避免运行一堆其他不必要的中间件,它应该靠近列表的顶部。
-
之前修改
Vary
头(SessionMiddleware
,GZipMiddleware
,LocaleMiddleware
)。 -
在任何可能更改或使用响应主体的中间件之前。
UpdateCacheMiddleware
后:修改Vary
头。 -
在
CommonMiddleware
之前:当USE_ETAGS
=True
时使用其ETag
报头。 -
UpdateCacheMiddleware
后:修改Vary
头。 -
SessionMiddleware
(使用会话数据)和UpdateCacheMiddleware
(修改Vary
头)之后的最顶层之一。 -
在任何中间件可能改变响应之前(它计算
ETags
)。在
GZipMiddleware
之后,它不会在gzip压缩的内容上计算ETag
头。靠近顶部:当
APPEND_SLASH
或PREPEND_WWW
设置为True
时,它重定向。 -
在任何视图中间件假定已经处理CSRF攻击之前。
-
SessionMiddleware
后:使用会话存储。 -
SessionMiddleware
后:可以使用基于会话的存储。 -
在修改
Vary
头部的任何中间件之后:该头部用于为高速缓存哈希键选择值。 -
应该在底部附近,因为它是最后一种手段类型的中间件。
-
应该在底部附近,因为它是最后一种手段类型的中间件。