可用的中间件
缓存中间件
django.middleware.cache.UpdateCacheMiddleware; 和
django.middleware.cache.FetchFromCacheMiddleware
启用站点范围的缓存。 如果启用了这些功能,只要CACHE_MIDDLEWARE_SECONDS设置定义,每个Django驱动的页面都将被缓存。 请参阅缓存文档。
通用中间件
django.middleware.common.CommonMiddleware
为完美主义者增添了一些便利:
-
禁止访问DISALLOWED_USER_AGENTS设置中的用户代理,该设置应该是已编译的正则表达式对象的列表。
-
根据APPEND_SLASH和PREPEND_WWW设置执行URL重写。如果APPEND_SLASH为True,并且初始URL不以斜线结尾,并且在URLconf中找不到,则通过在末尾附加斜杠形成新URL。如果在URLconf中找到这个新的URL,那么Django会将请求重定向到这个新的URL。否则,将像往常一样处理初始URL。例如,如果您没有foo.com/bar的有效URL模式,但foo.com/bar会被重定向到foo.com/bar/,但确实有一个有效的模式为foo.com/bar/。
如果PREPEND_WWW为True,则缺少领先的www的URL。将通过领先的www重定向到相同的URL。
这两个选项都是为了规范化网址。哲学是每个URL应该存在于一个地方,并且只存在于一个地方。从技术上来说,foo.com/bar与foo.com/bar/不同 - 搜索引擎索引器会将它们视为单独的URL - 因此最佳做法是对URL进行规范化。 -
基于USE_ETAGS设置处理ETags。如果USE_ETAGS设置为True,则Django将通过MD5散列页面内容为每个请求计算一个ETag,并且如果适当,它将负责发送Not Modified响应。
CommonMiddleware.response_redirect_class。默认为HttpResponsePermanentRedirect。子类CommonMiddleware并覆盖该属性以自定义由中间件发出的重定向。 -
django.middleware.common.BrokenLinkEmailsMiddleware。将损坏的链接通知电子邮件发送给MANAGERS。
GZip中间件
django.middleware.gzip.GZipMiddleware
安全研究人员最近透露,当在网站上使用压缩技术(包括GZipMiddleware)时,该网站会受到一系列可能的攻击。 除其他外,这些方法可用于妥协Django的CSRF保护。 在您的网站上使用GZipMiddleware之前,您应该非常仔细地考虑您是否受到这些攻击。 如果您对是否受到影响有任何疑问,则应避免使用GZipMiddleware。 有关更多详细信息,请参阅breachattack.com。
压缩理解GZip压缩的浏览器的内容(所有现代浏览器)。
这个中间件应该放在任何其他需要读或写响应体的中间件之前,以便后来进行压缩。
如果满足以下任何条件,它将不压缩内容:
- 内容正文长度小于200个字节。
- 该响应已经设置了Content-Encoding标头。
- 请求(浏览器)未发送包含gzip的Accept-Encoding标头。
您可以使用gzip_page()修饰器将GZip压缩应用于各个视图。
有条件的GET中间件
django.middleware.http.ConditionalGetMiddleware
处理有条件的GET操作。 如果响应具有ETag或Last-Modified标头,并且请求具有If-None-Match或If-Modified-Since,则该响应将被替换为HttpResponseNotModified。
还设置Date和Content-Length响应头。
区域设置中间件
django.middleware.locale.LocaleMiddleware
根据请求中的数据启用语言选择。 它为每个用户定制内容。 请参阅国际化文档。
LocaleMiddleware.response_redirect_class默认为HttpResponseRedirect。 子类LocaleMiddleware并覆盖该属性以自定义由中间件发出的重定向。
消息中间件
django.contrib.messages.middleware.MessageMiddleware
启用基于cookie和会话的消息支持。 请参阅消息文档。
安全中间件
如果您的部署情况允许,让前端Web服务器执行SecurityMiddleware提供的功能通常是个好主意。 这样,如果存在不被Django提供服务的请求(例如静态媒体或用户上传的文件),它们将具有与对Django应用程序的请求相同的保护。
django.middleware.security.SecurityMiddleware为请求/响应周期提供了多项安全增强功能。 SecurityMiddleware通过将特殊标头传递给浏览器来实现这一点。 每个人都可以独立启用或禁用设置。
HTTP严格传输安全
设置:
- SECURE_HSTS_INCLUDE_SUBDOMAINS
- SECURE_HSTS_SECONDS
对于只应通过HTTPS访问的网站,您可以通过设置Strict-Transport-Security标头,指示现代浏览器拒绝通过不安全连接(在给定的时间段内)连接到您的域名。这减少了您对某些SSL剥离中间人(MITM)攻击的暴露。
如果将SECURE_HSTS_SECONDS设置为非零整数值,SecurityMiddleware将为您在所有HTTPS响应中设置此标题。
启用HSTS时,首先使用小值进行测试是一个好主意,例如SECURE_HSTS_SECONDS = 3600一小时。每次Web浏览器从您的站点看到HSTS标头时,它都会拒绝在给定的时间段内与您的域进行非安全通信(使用HTTP)。
一旦您确认所有资产已在您的网站上安全使用(即HSTS没有破坏任何内容),最好增加此值以便不频繁的访问者受到保护(31536000秒,即1年是常见的)。
此外,如果将SECURE_HSTS_INCLUDE_SUBDOMAINS设置设置为True,SecurityMiddleware会将includeSubDomains标记添加到Strict-Transport-Security标头。建议这样做(假设所有子域都是使用HTTPS专门服务的),否则您的网站仍可能通过与子域的不安全连接而受到攻击。
HSTS策略适用于您的整个域,而不仅仅是您设置标题的响应的URL。 因此,只有在您的整个域名仅通过HTTPS提供服务时,您才应该使用它。浏览器正确地遵守HSTS标头将拒绝允许用户绕过警告并连接到具有过期,自签名或其他无效SSL证书的网站。 如果您使用HSTS,请确保您的证书状态良好并保持这种状态!
X-Content-Type-Options: nosniff
设置:
- SECURE_CONTENT_TYPE_NOSNIFF
一些浏览器会尝试猜测他们获取的资产的内容类型,覆盖Content-Type标题。虽然这可以帮助显示配置不正确的服务器的网站,但它也可能带来安全风险。
如果您的网站提供用户上传的文件,恶意用户可以上传一个特制的文件,当您预期它是无害的时候,浏览器会将其解释为HTML或Javascript。
为了防止浏览器猜测内容类型并强制它始终使用Content-Type标头中提供的类型,可以传递X-Content-Type-Options:nosniff标头。如果SECURE_CONTENT_TYPE_NOSNIFF设置为True,SecurityMiddleware将为所有响应执行此操作。
请注意,在大多数部署情况下,Django不参与提供用户上传的文件,该设置不会对您有所帮助。例如,如果您的MEDIA_URL由您的前端Web服务器(nginx,Apache等)直接提供,那么您需要在此设置此标头。
另一方面,如果您使用Django来执行类似于需要授权的操作来下载文件,并且无法使用Web服务器设置标题,则此设置将非常有用。
X-XSS-Protection
设置:
- SECURE_BROWSER_XSS_FILTER
某些浏览器可以阻止似乎是XSS攻击的内容。 他们通过在页面的GET或POST参数中查找Javascript内容来工作。 如果Javascript在服务器响应中重播,页面将被阻止呈现,并显示错误页面。
X-XSS-Protection头用于控制XSS过滤器的操作。
要在浏览器中启用XSS过滤器,并强制它始终阻止可疑的XSS攻击,可以通过X-XSS-Protection:1; mode =block头。 如果SECURE_BROWSER_XSS_FILTER设置为True,SecurityMiddleware将为所有响应执行此操作。
浏览器XSS过滤器是一种有用的防御措施,但不能完全依赖。 它无法检测到所有XSS攻击,并且并非所有浏览器都支持该头部。 确保您仍在验证所有输入以防止XSS攻击。
SSL 重定向
设置:
- SECURE_REDIRECT_EXEMPT
- SECURE_SSL_HOST
- SECURE_SSL_REDIRECT
如果您的站点同时提供HTTP和HTTPS连接,则默认情况下,大多数用户最终将得到不安全的连接。为了获得最佳安全性,您应该将所有HTTP连接重定向到HTTPS。
如果将SECURE_SSL_REDIRECT设置为True,则SecurityMiddleware将永久(HTTP 301)将所有HTTP连接重定向到HTTPS。
出于性能原因,最好在Django以外的前端负载均衡器或反向代理服务器(如nginx)中执行这些重定向。 SECURE_SSL_REDIRECT适用于不适用的部署情况。
如果SECURE_SSL_HOST设置具有值,则所有重定向都将发送到该主机,而不是原始请求的主机。
如果网站上有几个页面应该可通过HTTP访问,并且未重定向到HTTPS,则可以列出正则表达式以匹配SECURE_REDIRECT_EXEMPT设置中的这些URL。
如果您部署在负载平衡器或反向代理服务器后面,并且Django似乎无法确定请求实际上已经安全,您可能需要设置SECURE_PROXY_SSL_HEADER设置。
会话中间件
django.contrib.sessions.middleware.SessionMiddleware
启用会话支持。 有关更多信息,请参阅第15章。
网站中间件
django.contrib.sites.middleware.CurrentSiteMiddleware
添加该网站
属性表示当前站点到每个传入的HttpRequest对象。 有关更多信息,请参阅网站文档。
身份验证中间件
django.contrib.auth.middleware提供了三种用于身份验证的中间件:
-
*.AuthenticationMiddleware。 将表示当前登录用户的用户属性添加到每个传入的HttpRequest对象。
-
*.RemoteUserMiddleware。 利用Web服务器提供的身份验证的中间件。
-
.SessionAuthenticationMiddleware。 允许用户的会话在密码更改时失效。 此中间件必须出现在MIDDLEWARE_CLASSES中的 .AuthenticationMiddleware之后。
有关Django中用户认证的更多信息,请参阅第11章。
CSRF保护中间件
django.middleware.csrf.CsrfViewMiddleware
通过向POST表单添加隐藏的表单字段并检查请求以获取正确的值,添加对跨站请求伪造(CSRF)的保护。 有关CSRF保护的更多信息,请参阅第19章。
X-Frame-Options中间件
django.middleware.clickjacking.XFrameOptionsMiddleware
通过X-Frame-Options标头实现简单的点击劫持保护。
中间件订购
表17-1提供了有关各种Django中间件类的排序的一些提示:
表17-1:中间件类的排序
类 | 说明 |
---|---|
UpdateCacheMiddleware | 在那些修改Vary头部之前(SessionMiddleware,GZipMiddleware,LocaleMiddleware)。 |
GZipMiddleware | 在任何可能改变或使用响应主体的中间件之前。 UpdateCacheMiddleware之后:修改Vary标题。 |
ConditionalGetMiddleware | CommonMiddleware之前:当USE_ETAGS = True时使用它的Etag标头。 |
SessionMiddleware | UpdateCacheMiddleware之后:修改Vary标题。 |
LocaleMiddleware | 在SessionMiddleware(使用会话数据)和CacheMiddleware(修改Vary头)之后的最顶层之一。 |
CommonMiddleware | 在任何可能改变响应的中间件之前(它计算ETags)。 在GZipMiddleware之后,它不会计算gzip内容上的ETag标头。 靠近顶部:APPEND_SLASH或PREPEND_WWW设置为True时重定向。 |
CsrfViewMiddleware | 在任何认为CSRF攻击已被处理的中间件之前。 |
AuthenticationMiddleware | SessionMiddleware之后:使用会话存储。 |
MessageMiddleware | SessionMiddleware之后:可以使用基于会话的存储。 |
FetchFromCacheMiddleware | 在修改Vary头的任何中间件之后:该头用于为缓存散列键选择一个值。 |
FlatpageFallbackMiddleware | 应该接近底部,因为它是最后一种类型的中间件。 |
RedirectFallbackMiddleware | 应该接近底部,因为它是最后一种类型的中间件。 |
下一步是什么?
在下一章中,我们将讨论Django的国际化。