本文档解释了Django附带的所有中间件组件。有关如何使用它们以及如何编写自己的中间件的信息,请参见 middleware usage guide .
启用站点范围的缓存。如果启用了这些,则只要 CACHE_MIDDLEWARE_SECONDS
设置定义。见 cache documentation .
为完美主义者增加了一些便利:
禁止访问中的用户代理 DISALLOWED_USER_AGENTS
设置,它应该是已编译正则表达式对象的列表。
基于执行URL重写 APPEND_SLASH
和 PREPEND_WWW
设置。
如果 APPEND_SLASH
是 True
初始URL没有以斜杠结尾,并且在urlconf中找不到它,然后在末尾附加斜杠来形成新的URL。如果在urlconf中找到这个新的url,那么django会将请求重定向到这个新的url。否则,初始URL会像往常一样被处理。
例如, foo.com/bar
将被重定向到 foo.com/bar/
如果没有有效的URL模式 foo.com/bar
但是 do 具有有效的模式 foo.com/bar/
.
如果 PREPEND_WWW
是 True
,缺少前导“www.”的URL将被重定向到具有前导“www”的同一URL。
这两个选项都是为了规范化URL。其原理是每个URL都应该存在于一个且只有一个的地方。技术上是一个URL foo.com/bar
不同于 foo.com/bar/
--搜索引擎索引器将它们视为单独的URL——所以规范化URL是最佳实践。
如有必要,个人观点可能会被排除在 APPEND_SLASH
使用 no_append_slash()
装饰师::
from django.views.decorators.common import no_append_slash
@no_append_slash
def sensitive_fbv(request, *args, **kwargs):
"""View to be excluded from APPEND_SLASH."""
return HttpResponse()
设置 Content-Length
非流式响应的头。
默认为 HttpResponsePermanentRedirect
. 子类 CommonMiddleware
并重写该属性以自定义中间件发出的重定向。
备注
安全研究人员透露,当压缩技术(包括 GZipMiddleware
)在网站上使用时,该网站可能会面临多个可能的攻击。
为了减轻攻击,Django实现了一种名为 Heal The Breach (HTB) 。它总共有100个字节(请参见 max_random_bytes
每个响应的随机字节),以降低攻击的有效性。
有关更多详细信息,请参阅 BREACH paper (PDF) , breachattack.com ,而 Heal The Breach (HTB) paper 。
这个 django.middleware.gzip.GZipMiddleware
为了解GZip压缩的浏览器(所有现代浏览器)压缩内容。
这个中间件应该放在任何其他需要读取或写入响应体的中间件之前,以便随后进行压缩。
如果以下任何一项为真,则不会压缩内容:
内容正文的长度小于200字节。
响应已设置 Content-Encoding
标题。
请求(浏览器)未发送 Accept-Encoding
包含标题 gzip
.
如果响应具有 ETag
标头,则ETag被设置为弱以符合 RFC 9110#section-8.8.1 。
您可以使用 gzip_page()
装饰符。
处理条件获取操作。如果响应没有 ETag
头,如果需要,中间件会添加一个。如果响应有 ETag
或 Last-Modified
头,请求 If-None-Match
或 If-Modified-Since
,响应被替换为 HttpResponseNotModified
.
您可以使用 conditional_page()
装饰师。
基于请求中的数据启用语言选择。它为每个用户定制内容。见 internationalization documentation .
默认为 HttpResponseRedirect
. 子类 LocaleMiddleware
并重写该属性以自定义中间件发出的重定向。
启用基于cookie和会话的消息支持。见 messages documentation .
警告
如果您的部署情况允许,让前端Web服务器执行由 SecurityMiddleware
。这样,如果有Django没有处理的请求(例如静态媒体或用户上传的文件),它们将得到与对Django应用程序的请求相同的保护。
这个 django.middleware.security.SecurityMiddleware
为请求/响应周期提供了几个安全增强。每个都可以通过一个设置单独启用或禁用。
对于只能通过HTTPS访问的网站,您可以通过设置 `"Strict-Transport-Security" header`__. 这可以减少您遭受一些SSL剥离中间人(MITA)攻击的风险。
SecurityMiddleware
如果设置 SECURE_HSTS_SECONDS
设置为非零整数值。
启用HSTS时,最好首先使用较小的值进行测试,例如, SECURE_HSTS_SECONDS = 3600
一小时。Web浏览器每次从您的站点看到HSTS标头时,都会拒绝在给定时间段内以非安全方式(使用HTTP)与您的域进行通信。一旦您确认所有资产都在您的站点上安全地提供服务(即HSTS没有损坏任何东西),最好增加此值,以便保护不经常访问的访问者(通常为31536000秒,即1年)。
此外,如果设置 SECURE_HSTS_INCLUDE_SUBDOMAINS
设置为 True
, SecurityMiddleware
将添加 includeSubDomains
指示 Strict-Transport-Security
标题。建议这样做(假设所有子域都是以https的方式提供服务的),否则您的站点仍然可能由于与子域的不安全连接而受到攻击。
如果您希望将站点提交到 browser preload list 设置 SECURE_HSTS_PRELOAD
设置为 True
. 它附加了 preload
指示 Strict-Transport-Security
标题。
警告
HSTS策略适用于整个域,而不仅仅是设置头的响应的URL。因此,仅当整个域仅通过HTTPS提供服务时才应使用它。
正确遵守hsts头的浏览器将拒绝允许用户绕过警告并连接到具有过期、自签名或其他无效SSL证书的站点。如果您使用HST,请确保您的证书状态良好,并保持这种状态!
备注
如果部署在负载均衡器或反向代理服务器之后,并且 Strict-Transport-Security
没有将头添加到响应中,这可能是因为Django没有意识到它在安全连接上;您可能需要设置 SECURE_PROXY_SSL_HEADER
设置。
浏览器使用 `the Referer header`__ 作为向网站发送有关用户如何到达那里的信息的一种方式。当用户单击链接时,浏览器将发送链接页面的完整URL作为提示者。虽然这对于某些目的可能很有用(例如弄清楚谁正在链接到您的网站),但它也可能会通过通知一个网站用户正在访问另一个网站而引起隐私问题。
一些浏览器能够接受有关是否应该发送HTTP的提示 Referer
header when a user clicks a link; this hint is provided via `the Referrer-Policy header`__. 此标头可以向浏览器建议三种行为中的任何一种:
完整URL:在 Referer
标头例如,如果用户正在访问 https://example.com/page.html
vt.的. Referer
标题将包含 "https://example.com/page.html"
。
仅起源:仅发送者中的“起源”。起源由方案、主机和(可选)端口号组成。例如,如果用户正在访问 https://example.com/page.html
,起源是 https://example.com/
。
没有警告者:不要发送 Referer
根本没有标题。
此标题可以告诉浏览器注意两种类型的情况:
同源与跨源:来自 https://example.com/1.html
至 https://example.com/2.html
是同一起源的。一个链接从 https://example.com/page.html
至 https://not.example.com/page.html
是跨起源的。
协议降级:如果包含链接的页面通过HTTPS提供,但链接到的页面不通过HTTPS提供,则会发生降级。
警告
当您的站点通过HTTPS提供服务时, Django's CSRF protection system 需要 Referer
标头存在,因此完全禁用 Referer
报头将干扰CSRF保护。要获得禁用的大部分好处 Referer
在保持CSRF保护的同时,考虑只启用同源引用。
SecurityMiddleware
可以设置 Referrer-Policy
标头,基于 SECURE_REFERRER_POLICY
设置(注意拼写:浏览器发送 Referer
当用户单击链接时,标题,但指示浏览器是否这样做的标题拼写为 Referrer-Policy
).此设置的有效值是:
no-referrer
指示浏览器不发送此网站上单击的链接的警告。
no-referrer-when-downgrade
指示浏览器发送完整的URL作为警告者,但仅在未发生协议降级时发送。
origin
指示浏览器仅发送来源,而不是完整的URL作为发送者。
origin-when-cross-origin
指示浏览器发送完整的URL作为同源链接的发送者,而仅发送跨源链接的来源。
same-origin
指示浏览器发送完整的URL,但仅针对相同来源的链接。不会为跨来源链接发送任何通知。
strict-origin
指示浏览器仅发送源,而不是完整的URL,并且在发生协议降级时不发送任何警告。
strict-origin-when-cross-origin
当链接是同源且未发生协议降级时,指示浏览器发送完整的URL;当链接是跨源且未发生协议降级时,指示浏览器仅发送源;当发生协议降级时,指示浏览器不发送警告。
unsafe-url
指示浏览器始终将完整的URL作为发送者发送。
未知的政策价值观
政策价值在哪里 `unknown`__ 通过用户代理,可以指定多个策略值来提供后备。所理解的最后指定值优先。为了支持这一点,可以使用可迭代或逗号分隔的字符串 SECURE_REFERRER_POLICY
。
某些浏览器能够将顶级窗口与其他文档隔离开来,方法是根据 `Cross-Origin Opener Policy`__ (Coop)标题。如果以这种方式隔离的文档打开跨域弹出窗口,则弹出窗口的 window.opener
属性将是 null
。使用Coop隔离窗口是针对跨来源攻击的深度防御,特别是像Spectre这样的攻击,它允许加载到共享浏览上下文中的数据外泄。
SecurityMiddleware
可以设置 Cross-Origin-Opener-Policy
标头,基于 SECURE_CROSS_ORIGIN_OPENER_POLICY
布景。此设置的有效值为:
same-origin
将浏览上下文专门隔离到同源文档。跨来源的文档不会加载到相同的浏览上下文中。这是默认且最安全的选项。
same-origin-allow-popups
将浏览上下文隔离到同源文档或未设置coop的文档或通过设置 unsafe-none
。
unsafe-none
允许将文档添加到其打开者的浏览上下文组中,除非打开者本身具有 same-origin
或 same-origin-allow-popups
。
X-Content-Type-Options: nosniff
¶一些浏览器将尝试猜测其获取的资产的内容类型,覆盖 Content-Type
标题。虽然这有助于显示服务器配置不正确的站点,但也可能带来安全风险。
如果你的网站提供用户上传的文件,恶意用户可以上传一个精心制作的文件,当你期望它是无害的时,浏览器会将其解释为HTML或javascript。
为了防止浏览器猜测内容类型并强制它始终使用 Content-Type
头,你可以通过 X-Content-Type-Options: nosniff 标题。 SecurityMiddleware
如果 SECURE_CONTENT_TYPE_NOSNIFF
设置是 True
.
请注意,在Django不参与提供用户上传的文件的大多数部署情况下,此设置对您没有帮助。例如,如果您的 MEDIA_URL
由您的前端Web服务器(nginx、apache等)直接提供服务然后,您会想要在那里设置这个标题。另一方面,如果您正在使用Django执行诸如需要授权才能下载文件之类的操作,并且无法使用您的Web服务器设置头文件,则此设置将非常有用。
如果您的站点同时提供HTTP和HTTPS连接,那么默认情况下,大多数用户最终都会得到一个不安全的连接。为了获得最佳安全性,您应该将所有HTTP连接重定向到HTTPS。
如果你设置 SECURE_SSL_REDIRECT
设置为真, SecurityMiddleware
将永久(HTTP 301)重定向所有HTTP连接到HTTPS。
备注
出于性能原因,最好在Django之外、前端负载均衡器或反向代理服务器(如 nginx . SECURE_SSL_REDIRECT
用于不可选择的部署情况。
如果 SECURE_SSL_HOST
设置有一个值,所有重定向都将发送到该主机,而不是最初请求的主机。
如果您的站点上有几个页面应该可以通过HTTP访问,而不是重定向到HTTPS,则可以列出正则表达式以匹配 SECURE_REDIRECT_EXEMPT
设置。
备注
如果您部署在负载均衡器或反向代理服务器之后,Django似乎无法确定请求何时已经安全,则可能需要设置 SECURE_PROXY_SSL_HEADER
设置。
启用会话支持。见 session documentation .
添加 site
表示当前站点到每个传入站点的属性 HttpRequest
对象。见 sites documentation .
添加 user
属性,表示当前登录的用户。 HttpRequest
对象。看见 Authentication in web requests 。
将所有未经验证的请求重定向到登录页面。对于管理员视图,这将重定向到管理员登录名。对于所有其他视图,这将重定向到 settings.LOGIN_URL
.这可以通过使用 login_required()
装饰师和布景 login_url
或 redirect_field_name
为了景观。例如::
@method_decorator(
login_required(login_url="/login/", redirect_field_name="redirect_to"),
name="dispatch",
)
class MyView(View):
pass
@login_required(login_url="/login/", redirect_field_name="redirect_to")
def my_view(request): ...
使用的视图 login_not_required()
装饰师不受此要求的约束。
确保您的登录视图不需要登录。
为了防止无限重定向,请确保您有 enabled unauthenticated requests 到您的登录视图。
方法和属性
默认为 "next"
。
返回未经身份验证的请求将被重定向到的URL。如果已定义,则返回 login_url
上设置 login_required()
装饰师。默认为 settings.LOGIN_URL
。
返回查询参数的名称,该参数包含用户成功登录后应重定向到的URL。如果已定义,则返回 redirect_field_name
上设置 login_required()
装饰师。默认为 redirect_field_name
。如果 None
则不会添加查询参数。
用于利用Web服务器提供的身份验证的中间件。看见 如何使用进行身份验证 REMOTE_USER 了解用法详细信息。
当仅在登录页面上启用时,用于利用Web服务器提供的身份验证的中间件。看见 使用 REMOTE_USER 仅在登录页上 了解用法详细信息。
通过将隐藏的表单字段添加到发布表单并检查请求的正确值,添加对跨站点请求伪造的保护。见 Cross Site Request Forgery protection documentation .
您可以使用将跨站点请求伪造保护添加到各个视图 csrf_protect()
装饰师。
X-Frame-Options
中间件¶简单的 clickjacking protection via the X-Frame-Options header .
以下是有关各种django中间件类排序的一些提示:
如果您要打开SSL重定向,那么应该接近列表的顶部,因为这样可以避免运行其他一些不必要的中间件。
在那些修改 Vary
页眉 (SessionMiddleware
, GZipMiddleware
, LocaleMiddleware
)
在任何可能更改或使用响应主体的中间件之前。
后 UpdateCacheMiddleware
修改 Vary
标题。
在任何可能引发异常以触发错误视图的中间件(例如 PermissionDenied
)如果您正在使用 CSRF_USE_SESSIONS
。
后 UpdateCacheMiddleware
修改 Vary
标题。
在任何可能更改响应的中间件之前(它设置 ETag
标题)。
后 GZipMiddleware
所以它不能计算 ETag
gzip内容的标题。
最上面的一个,之后 SessionMiddleware
(使用会话数据)和 UpdateCacheMiddleware
(修改 Vary
标题)。
在任何可能更改响应的中间件之前(它设置 Content-Length
标题)。以前出现的中间件 CommonMiddleware
并更改响应必须重置 Content-Length
.
接近顶部:当 APPEND_SLASH
或 PREPEND_WWW
设置为 True
.
后 SessionMiddleware
如果你在用 CSRF_USE_SESSIONS
.
在任何假设已经处理了CSRF攻击的视图中间件之前。
之前 RemoteUserMiddleware
,或任何其他可以执行登录并因此在调用中间件链之前轮换CSRF令牌的验证中间件。
后 SessionMiddleware
如果你在用 CSRF_USE_SESSIONS
.
后 SessionMiddleware
:使用会话存储。
之后 AuthenticationMiddleware
:使用用户对象。
后 SessionMiddleware
:可以使用基于会话的存储。
在任何修改 Vary
header:这个header用于为缓存哈希键选择一个值。
应该接近底部,因为它是中间件的最后一种手段。
应该接近底部,因为它是中间件的最后一种手段。
7月 22, 2024