鍍金池/ 教程/ Python/ 中間件
點(diǎn)擊劫持保護(hù)
安全問(wèn)題歸檔
Model 類參考
將遺留數(shù)據(jù)庫(kù)整合到Django
關(guān)聯(lián)對(duì)象參考
內(nèi)建基于類的視圖的API
聚合
Django 中的用戶認(rèn)證
django.contrib.humanize
Django管理文檔生成器
分頁(yè)
使用Django輸出CSV
加密簽名
文件儲(chǔ)存API
安全
Django中的測(cè)試
國(guó)際化和本地化
為Django編寫首個(gè)補(bǔ)丁
條件表達(dá)式
日志
模型元選項(xiàng)
部署靜態(tài)文件
執(zhí)行查詢
使用Django認(rèn)證系統(tǒng)
基于類的視圖
中間件
編寫自定義的django-admin命令
Django 的設(shè)置
格式本地化
數(shù)據(jù)庫(kù)訪問(wèn)優(yōu)化
錯(cuò)誤報(bào)告
基于類的內(nèi)建通用視圖
編寫自定義存儲(chǔ)系統(tǒng)
編寫你的第一個(gè) Django 程序 第3部分
編寫數(shù)據(jù)庫(kù)遷移
使用表單
編寫你的第一個(gè) Django 程序 第2部分
編寫你的第一個(gè) Django 程序 第1部分
如何使用會(huì)話
系統(tǒng)檢查框架
新手入門
信號(hào)
編寫視圖
如何使用WSGI 部署
編寫你的第一個(gè)Django應(yīng)用,第6部分
常見(jiàn)的網(wǎng)站應(yīng)用工具
Widgets
內(nèi)建的視圖
模型實(shí)例參考
視圖層
Django中的密碼管理
高級(jí)教程:如何編寫可重用的應(yīng)用
國(guó)際化和本地化
"本地特色"附加功能
TemplateResponse 和 SimpleTemplateResponse
模式編輯器
文件上傳
快速安裝指南
部署 Django
表單 API
表單素材 ( <code>Media</code> 類)
管理文件
其它核心功能
查找 API 參考
表單
Admin
數(shù)據(jù)庫(kù)函數(shù)
自定義查找
使用基于類的視圖處理表單
管理操作
開(kāi)發(fā)過(guò)程
編寫你的第一個(gè)Django應(yīng)用,第5部分
進(jìn)行原始的sql查詢
模型層
多數(shù)據(jù)庫(kù)
編寫你的第一個(gè) Django 程序 第4部分
Django安全
Django 初探
Django異常
重定向應(yīng)用
按需內(nèi)容處理
管理器
視圖裝飾器
驗(yàn)證器
使用Django輸出PDF
File對(duì)象
Django 的快捷函數(shù)
基于類的通用視圖 —— 索引
為模型提供初始數(shù)據(jù)
模板層
URL調(diào)度器
中間件
模型

中間件

這篇文檔介紹了Django自帶的所有中間件組件。 要查看關(guān)于如何使用它們以及如何編寫自己的中間件,請(qǐng)見(jiàn)中間件使用指導(dǎo)。

可用的中間件

緩存中間件

class UpdateCacheMiddleware[source]

class FetchFromCacheMiddleware[source]

開(kāi)啟全站范圍的緩存。 如果開(kāi)啟了這些緩存,任何一個(gè)由Django提供的頁(yè)面將會(huì)被緩存,緩存時(shí)長(zhǎng)是由你在CACHE_MIDDLEWARE_SECONDS配置中定義的。詳見(jiàn)緩存文檔。

"常用"的中間件

class CommonMiddleware[source]

給完美主義者增加一些便利條件:

  • 禁止訪問(wèn)DISALLOWED_USER_AGENTS中設(shè)置的用戶代理,這項(xiàng)配置應(yīng)該是一個(gè)已編譯的正則表達(dá)式對(duì)象的列表。
  • 基于APPEND_SLASH和PREPEND_WWW的設(shè)置來(lái)重寫URL。

如果APPEND_SLASH設(shè)為True并且一開(kāi)始的的URL沒(méi)有以斜線結(jié)尾,并且在URLconf中也沒(méi)找到對(duì)應(yīng)定義,這時(shí)形成一個(gè)一個(gè)斜線結(jié)尾新的URL。如果這個(gè)新的URL存在于URLconf,這時(shí)Django會(huì)重定向請(qǐng)求到這個(gè)新URL上,否則,一開(kāi)始的URL按正常情況處理。

比如,foo.com/bar將會(huì)被重定向到foo.com/bar/,如果你沒(méi)有為foo.com/bar定義有效的正則,但是為foo.com/bar/定義了有效的正則。

如果PREPEND_WWW設(shè)為True,前面缺少 "www."的url將會(huì)被重定向到相同但是以一個(gè)"www."開(kāi)頭的url。

兩種選項(xiàng)都是為了規(guī)范化url。其中的哲學(xué)就是,任何一個(gè)url應(yīng)該在一個(gè)地方僅存在一個(gè)。技術(shù)上來(lái)講,url foo.com/bar 區(qū)別于foo.com/bar/ -- 搜索引擎索引會(huì)把這里分開(kāi)處理 -- 因此,最佳實(shí)踐就是規(guī)范化url。

  • 基于 USE_ETAGS 設(shè)置來(lái)處理ETag。如果設(shè)置USE_ETAGS為True,Django會(huì)通過(guò)MD5-hashing處理頁(yè)面的內(nèi)容來(lái)為每一個(gè)頁(yè)面請(qǐng)求計(jì)算Etag,并且如果合適的話,它將會(huì)發(fā)送攜帶Not Modified的響應(yīng)。

CommonMiddleware.response_redirect_class

Django 1.8中新增

默認(rèn)為HttpResponsePermanentRedirect。它繼承了CommonMiddleware,并覆寫了屬性來(lái)自定義中間件發(fā)出的重定向。

class BrokenLinkEmailsMiddleware[source]

  • 向MANAGERS發(fā)送死鏈提醒郵件(詳見(jiàn)錯(cuò)誤報(bào)告)。

GZip中間件

class GZipMiddleware[source]

警告

安全研究員最近發(fā)現(xiàn),當(dāng)壓縮技術(shù)(包括GZipMiddleware)用于一個(gè)網(wǎng)站的時(shí)候,網(wǎng)站會(huì)受到一些可能的攻擊。此外,這些方法可以用于破壞Django的CSRF保護(hù)。在你的站點(diǎn)使用GZipMiddleware之前,你應(yīng)該先仔細(xì)考慮一下你的站點(diǎn)是否容易受到這些攻擊。 如果你不確定是否會(huì)受到這些影響,應(yīng)該避免使用 GZipMiddleware。詳見(jiàn)the BREACH paper (PDF)和breachattack.com。

為支持GZip壓縮的瀏覽器(一些現(xiàn)代的瀏覽器)壓縮內(nèi)容。

建議把這個(gè)中間件放到中間件配置列表的第一個(gè),這樣壓縮響應(yīng)內(nèi)容的處理會(huì)到最后才 發(fā)生。

如果滿足下面條件的話,內(nèi)容不會(huì)被壓縮:

  • 消息體的長(zhǎng)度小于200個(gè)字節(jié)。
  • 響應(yīng)已經(jīng)設(shè)置了Content-Encoding協(xié)議頭。
  • 請(qǐng)求(瀏覽器)沒(méi)有發(fā)送包含gzip的Accept-Encoding協(xié)議頭。

你可以通過(guò)這個(gè)gzip_page()裝飾器使用獨(dú)立的GZip壓縮。

帶條件判斷的GET中間件

class ConditionalGetMiddleware[source]

處理帶有條件判斷狀態(tài)GET操作。 如果一個(gè)請(qǐng)求包含 ETag 或者Last-Modified協(xié)議頭,并且請(qǐng)求包含If-None-Match或If-Modified-Since,這時(shí)響應(yīng)會(huì)被 替換為HttpResponseNotModified。

另外,它會(huì)設(shè)置Date和Content-Length響應(yīng)頭。

本地中間件

class LocaleMiddleware[source]

基于請(qǐng)求中的數(shù)據(jù)開(kāi)啟語(yǔ)言選擇。 它可以為每個(gè)用戶進(jìn)行定制。 詳見(jiàn)國(guó)際化文檔。

LocaleMiddleware.response_redirect_class

默認(rèn)為HttpResponseRedirect。繼承自LocaleMiddleware并覆寫了屬性來(lái)自定義中間件發(fā)出的重定向。

消息中間件

class MessageMiddleware[source]

開(kāi)啟基于cookie或會(huì)話的消息支持。詳見(jiàn)消息文檔。

安全中間件

警告

如果你的部署環(huán)境允許的話,讓你的前端web服務(wù)器展示SecurityMiddleware提供的功能是個(gè)好主意。這樣一來(lái),如果有任何請(qǐng)求沒(méi)有被Django處理(比如靜態(tài)媒體或用戶上傳的文件),他們會(huì)擁有和向Django應(yīng)用的請(qǐng)求相同的保護(hù)。

class SecurityMiddleware[source]

Django 1.8中新增

django.middleware.security.SecurityMiddleware為請(qǐng)求/響應(yīng)循環(huán)提供了幾種安全改進(jìn)。每一種可以通過(guò)一個(gè)選項(xiàng)獨(dú)立開(kāi)啟或關(guān)閉。

  • SECURE_BROWSER_XSS_FILTER
  • SECURE_CONTENT_TYPE_NOSNIFF
  • SECURE_HSTS_INCLUDE_SUBDOMAINS
  • SECURE_HSTS_SECONDS
  • SECURE_REDIRECT_EXEMPT
  • SECURE_SSL_HOST
  • SECURE_SSL_REDIRECT

HTTP Strict Transport Security (HSTS)

對(duì)于那些應(yīng)該只能通過(guò)HTTPS訪問(wèn)的站點(diǎn),你可以通過(guò)設(shè)置HSTS協(xié)議頭,通知現(xiàn)代的瀏覽器,拒絕用不安全的連接來(lái)連接你的域名。這會(huì)降低你受到SSL-stripping的中間人(MITM)攻擊的風(fēng)險(xiǎn)。

如果你將SECURE_HSTS_SECONDS設(shè)置為一個(gè)非零值,SecurityMiddleware會(huì)在所有的HTTPS響應(yīng)中設(shè)置這個(gè)協(xié)議頭。

開(kāi)啟HSTS的時(shí)候,首先使用一個(gè)小的值來(lái)測(cè)試它是個(gè)好主意,例如,讓SECURE_HSTS_SECONDS = 3600為一個(gè)小時(shí)。每當(dāng)瀏覽器在你的站點(diǎn)看到HSTS協(xié)議頭,都會(huì)在提供的時(shí)間段內(nèi)絕對(duì)使用不安全(HTTP)的方式連接到你的域名。一旦你確認(rèn)你站點(diǎn)上的所有東西都以安全的方式提供(例如,HSTS并不會(huì)干擾任何事情),建議你增加這個(gè)值,這樣不常訪問(wèn)你站點(diǎn)的游客也會(huì)被保護(hù)(比如,一般設(shè)置為31536000秒,一年)。

另外,如果你將 SECURE_HSTS_INCLUDE_SUBDOMAINS設(shè)置為True,,SecurityMiddleware會(huì)將includeSubDomains標(biāo)簽添加到Strict-Transport-Security協(xié)議頭中。強(qiáng)烈推薦這樣做(假設(shè)所有子域完全使用HTTPS),否則你的站點(diǎn)仍舊有可能由于子域的不安全連接而受到攻擊。

警告

HSTS策略在你的整個(gè)域中都被應(yīng)用,不僅僅是你所設(shè)置協(xié)議頭的響應(yīng)中的url。所以,如果你的整個(gè)域都設(shè)置為HTTPS only,你應(yīng)該只使用HSTS策略。

適當(dāng)遵循HSTS協(xié)議頭的瀏覽器,會(huì)通過(guò)顯示警告的方式,拒絕讓用戶連接到證書過(guò)期的、自行簽署的、或者其他SSL證書無(wú)效的站點(diǎn)。如果你使用了HSTS,確保你的證書處于一直有效的狀態(tài)!

注意

如果你的站點(diǎn)部署在負(fù)載均衡器或者反向代理之后,并且Strict-Transport-Security協(xié)議頭沒(méi)有添加到你的響應(yīng)中,原因是Django有可能意識(shí)不到這是一個(gè)安全連接。你可能需要設(shè)置SECURE_PROXY_SSL_HEADER。

X-Content-Type-Options: nosniff

一些瀏覽器會(huì)嘗試猜測(cè)他們所得內(nèi)容的類型,而不是讀取Content-Type協(xié)議頭。雖然這樣有助于配置不當(dāng)?shù)姆?wù)器正常顯示內(nèi)容,但也會(huì)導(dǎo)致安全問(wèn)題。

如果你的站點(diǎn)允許用戶上傳文件,一些惡意的用戶可能會(huì)上傳一個(gè)精心構(gòu)造的文件,當(dāng)你覺(jué)得它無(wú)害的時(shí)候,文件會(huì)被瀏覽器解釋成HTML或者Javascript。

欲知更多有關(guān)這個(gè)協(xié)議頭和瀏覽器如何處理它的內(nèi)容,你可以在IE安全博客中讀到它。

要防止瀏覽器猜測(cè)內(nèi)容類型,并且強(qiáng)制它一直使用 Content-Type協(xié)議頭中提供的類型,你可以傳遞X-Content-Type-Options: nosniff協(xié)議頭。SecurityMiddleware將會(huì)對(duì)所有響應(yīng)這樣做,如果SECURE_CONTENT_TYPE_NOSNIFF 設(shè)置為True。

注意在大多數(shù)Django不涉及處理上傳文件的部署環(huán)境中,這個(gè)設(shè)置不會(huì)有任何幫助。例如,如果你的MEDIA_URL被前端web服務(wù)器直接處理(例如nginx和Apache),你可能想要在那里設(shè)置這個(gè)協(xié)議頭。而在另一方面,如果你使用Django執(zhí)行為了下載文件而請(qǐng)求授權(quán)之類的事情,并且你不能使用你的web服務(wù)器設(shè)置協(xié)議頭,這個(gè)設(shè)置會(huì)很有用。

X-XSS-Protection: 1; mode=block

一些瀏覽器能夠屏蔽掉出現(xiàn)XSS攻擊的內(nèi)容。通過(guò)尋找頁(yè)面中GET或者POST參數(shù)中的JavaScript內(nèi)容來(lái)實(shí)現(xiàn)。如果JavaScript在服務(wù)器的響應(yīng)中被重放,頁(yè)面就會(huì)停止渲染,并展示一個(gè)錯(cuò)誤頁(yè)來(lái)取代。

X-XSS-Protection協(xié)議頭用來(lái)控制XSS過(guò)濾器的操作。

要在瀏覽器中啟用XSS過(guò)濾器,并且強(qiáng)制它一直屏蔽可疑的XSS攻擊,你可以在協(xié)議頭中傳遞X-XSS-Protection: 1; mode=block。 如果SECURE_BROWSER_XSS_FILTER設(shè)置為True,SecurityMiddleware會(huì)在所有響應(yīng)中這樣做。

警告

瀏覽器的XSS過(guò)濾器是一個(gè)十分有效的手段,但是不要過(guò)度依賴它。它并不能檢測(cè)到所有的XSS攻擊,也不是所有瀏覽器都支持這一協(xié)議頭。確保你校驗(yàn)和過(guò)濾了所有的輸入來(lái)防止XSS攻擊。

SSL重定向

如果你同時(shí)提供HTTP和HTTPS連接,大多數(shù)用戶會(huì)默認(rèn)使用不安全的(HTTP)鏈接。為了更高的安全性,你應(yīng)該講所有HTTP連接重定向到HTTP連接。

如果你將SECURE_SSL_REDIRECT設(shè)置為True,SecurityMiddleware會(huì)將HTTP鏈接永久地(HTTP 301,permanently)重定向到HTTPS連接。

注意

由于性能因素,最好在Django外面執(zhí)行這些重定向,在nginx這種前端負(fù)載均衡器或者反向代理服務(wù)器中執(zhí)行。SECURE_SSL_REDIRECT專門為這種部署情況而設(shè)計(jì),當(dāng)這不可選擇的時(shí)候。

如果SECURE_SSL_HOST設(shè)置有一個(gè)值,所有重定向都會(huì)發(fā)到值中的主機(jī),而不是原始的請(qǐng)求主機(jī)。

如果你站點(diǎn)上的一些頁(yè)面應(yīng)該以HTTP方式提供,并且不需要重定向到HTTPS,你可以SECURE_REDIRECT_EXEMPT設(shè)置中列出匹配那些url的正則表達(dá)式。

注意

如果你在負(fù)載均衡器或者反向代理服務(wù)器后面部署應(yīng)用,而且Django不能辨別出什么時(shí)候一個(gè)請(qǐng)求是安全的,你可能需要設(shè)置SECURE_PROXY_SSL_HEADER。

會(huì)話中間件

class SessionMiddleware[source]

開(kāi)啟會(huì)話支持。詳見(jiàn)會(huì)話文檔。

站點(diǎn)中間件

class CurrentSiteMiddleware[source]

Django 1.7中新增

向每個(gè)接收到的HttpRequest對(duì)象添加一個(gè)site屬性,表示當(dāng)前的站點(diǎn)。詳見(jiàn)站點(diǎn)文檔。

認(rèn)證中間件

class AuthenticationMiddleware[source]

向每個(gè)接收到的HttpRequest對(duì)象添加user屬性,表示當(dāng)前登錄的用戶。詳見(jiàn)web請(qǐng)求中的認(rèn)證。

class RemoteUserMiddleware[source]

使用web服務(wù)器提供認(rèn)證的中間件。詳見(jiàn)使用REMOTE_USER進(jìn)行認(rèn)證。

class SessionAuthenticationMiddleware[source]

Django 1.7中新增

當(dāng)用戶修改密碼的時(shí)候使用戶的會(huì)話失效。詳見(jiàn)密碼更改時(shí)的會(huì)話失效。在MIDDLEWARE_CLASSES中,這個(gè)中間件必須出現(xiàn)在django.contrib.auth.middleware.AuthenticationMiddleware之后。

CSRF保護(hù)中間件

class CsrfViewMiddleware[source]

添加跨站點(diǎn)請(qǐng)求偽造的保護(hù),通過(guò)向POST表單添加一個(gè)隱藏的表單字段,并檢查請(qǐng)求中是否有正確的值。詳見(jiàn)CSRF保護(hù)文檔。

X-Frame-Options中間件

class XFrameOptionsMiddleware[source]

通過(guò)X-Frame-Options協(xié)議頭進(jìn)行簡(jiǎn)單的點(diǎn)擊劫持保護(hù)。

中間件的排序

下面是一些關(guān)于Django中間件排序的提示。

UpdateCacheMiddleware

放在修改大量協(xié)議頭的中間件(SessionMiddleware, GZipMiddleware, LocaleMiddleware)之前。

GZipMiddleware

放在任何可能修改或使用響應(yīng)消息體的中間件之前。

放在UpdateCacheMiddleware之后:會(huì)修改大量的協(xié)議頭。

ConditionalGetMiddleware

放在CommonMiddleware之前:當(dāng)USE_ETAGS = True時(shí)會(huì)使用它的Etag 協(xié)議頭。

SessionMiddleware

放在UpdateCacheMiddleware之后:會(huì)修改 大量協(xié)議頭。

LocaleMiddleware

放在SessionMiddleware(由于使用會(huì)話數(shù)據(jù))和 CacheMiddleware(由于要修改大量協(xié)議頭)之后的最上面。

CommonMiddleware

放在任何可能修改相應(yīng)的中間件之前(因?yàn)樗鼤?huì)生成ETags)。

在GZipMiddleware之后,不會(huì)在壓縮后的內(nèi)容上再去生成ETag。

盡可能放在靠上面的位置,因?yàn)锳PPEND_SLASH或者PREPEND_WWW設(shè)置為 True時(shí)會(huì)被重定向。

CsrfViewMiddleware

放在任何假設(shè)CSRF攻擊被處理的視圖中間件之前。

AuthenticationMiddleware

放在SessionMiddleware之后:因?yàn)樗褂脮?huì)話存儲(chǔ)。

MessageMiddleware

放在SessionMiddleware之后:會(huì)使用基于會(huì)話的存儲(chǔ)。

FetchFromCacheMiddleware

放在任何修改大量協(xié)議頭的中間件之后:協(xié)議頭被用來(lái)從緩存的哈希表中獲取值。

FlatpageFallbackMiddleware

應(yīng)該放在最底下,因?yàn)樗侵虚g件中的底牌。

RedirectFallbackMiddleware

應(yīng)該放在最底下,因?yàn)樗侵虚g件中的底牌。