天天看點

django 1.8 官方文檔翻譯: 3-6-2 内建的中間件中間件

Django 文檔協作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質。

交流群:467338606

網站:

http://python.usyiyi.cn/django/index.html

中間件

這篇文檔介紹了Django自帶的所有中間件元件。 要檢視關于如何使用它們以及如何編寫自己的中間件,請見中間件使用指導。

可用的中間件

緩存中間件

class UpdateCacheMiddleware[source]

class FetchFromCacheMiddleware[source]

開啟全站範圍的緩存。 如果開啟了這些緩存,任何一個由Django提供的頁面将會被緩存,緩存時長是由你在CACHE_MIDDLEWARE_SECONDS配置中定義的。詳見緩存文檔。

“常用”的中間件

class CommonMiddleware[source]

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

  • 禁止通路DISALLOWED_USER_AGENTS中設定的使用者代理,這項配置應該是一個已編譯的正規表達式對象的清單。
  • 基于APPEND_SLASH和PREPEND_WWW的設定來重寫URL。

如果APPEND_SLASH設為True并且一開始的的URL沒有以斜線結尾,并且在URLconf中也沒找到對應定義,這時形成一個一個斜線結尾新的URL。如果這個新的URL存在于URLconf,這時Django會重定向請求到這個新URL上,否則,一開始的URL按正常情況處理。

比如,foo.com/bar将會被重定向到foo.com/bar/,如果你沒有為foo.com/bar定義有效的正則,但是為foo.com/bar/定義了有效的正則。

如果PREPEND_WWW設為True,前面缺少 “www.”的url将會被重定向到相同但是以一個”www.”開頭的url。

兩種選項都是為了規範化url。其中的哲學就是,任何一個url應該在一個地方僅存在一個。技術上來講,url foo.com/bar 差別于foo.com/bar/ – 搜尋引擎索引會把這裡分開處理 – 是以,最佳實踐就是規範化url。

  • 基于 USE_ETAGS 設定來處理ETag。如果設定USE_ETAGS為True,Django會通過MD5-hashing處理頁面的内容來為每一個頁面請求計算Etag,并且如果合适的話,它将會發送攜帶Not Modified的響應。

CommonMiddleware.response_redirect_class

Django 1.8中新增           

預設為HttpResponsePermanentRedirect。它繼承了CommonMiddleware,并覆寫了屬性來自定義中間件發出的重定向。

class BrokenLinkEmailsMiddleware[source]

  • 向MANAGERS發送死鍊提醒郵件(詳見錯誤報告)。

GZip中間件

class GZipMiddleware[source]

警告

安全研究員最近發現,當壓縮技術(包括GZipMiddleware)用于一個網站的時候,網站會受到一些可能的攻擊。此外,這些方法可以用于破壞Django的CSRF保護。在你的站點使用GZipMiddleware之前,你應該先仔細考慮一下你的站點是否容易受到這些攻擊。 如果你不确定是否會受到這些影響,應該避免使用 GZipMiddleware。詳見the BREACH paper (PDF)和breachattack.com。

為支援GZip壓縮的浏覽器(一些現代的浏覽器)壓縮内容。

建議把這個中間件放到中間件配置清單的第一個,這樣壓縮響應内容的處理會到最後才 發生。

如果滿足下面條件的話,内容不會被壓縮:

  • 消息體的長度小于200個位元組。
  • 響應已經設定了Content-Encoding協定頭。
  • 請求(浏覽器)沒有發送包含gzip的Accept-Encoding協定頭。

你可以通過這個gzip_page()裝飾器使用獨立的GZip壓縮。

帶條件判斷的GET中間件

class ConditionalGetMiddleware[source]

處理帶有條件判斷狀态GET操作。 如果一個請求包含 ETag 或者Last-Modified協定頭,并且請求包含If-None-Match或If-Modified-Since,這時響應會被 替換為HttpResponseNotModified。

另外,它會設定Date和Content-Length響應頭。

本地中間件

class LocaleMiddleware[source]

基于請求中的資料開啟語言選擇。 它可以為每個使用者進行定制。 詳見國際化文檔。

LocaleMiddleware.response_redirect_class

預設為HttpResponseRedirect。繼承自LocaleMiddleware并覆寫了屬性來自定義中間件發出的重定向。

消息中間件

class MessageMiddleware[source]

開啟基于cookie或會話的消息支援。詳見消息文檔。

安全中間件

如果你的部署環境允許的話,讓你的前端web伺服器展示SecurityMiddleware提供的功能是個好主意。這樣一來,如果有任何請求沒有被Django處理(比如靜态媒體或使用者上傳的檔案),他們會擁有和向Django應用的請求相同的保護。

class SecurityMiddleware[source]

Django 1.8中新增           

django.middleware.security.SecurityMiddleware為請求/響應循環提供了幾種安全改進。每一種可以通過一個選項獨立開啟或關閉。

  • 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)

對于那些應該隻能通過HTTPS通路的站點,你可以通過設定HSTS協定頭,通知現代的浏覽器,拒絕用不安全的連接配接來連接配接你的域名。這會降低你受到SSL-stripping的中間人(MITM)攻擊的風險。

如果你将SECURE_HSTS_SECONDS設定為一個非零值,SecurityMiddleware會在所有的HTTPS響應中設定這個協定頭。

開啟HSTS的時候,首先使用一個小的值來測試它是個好主意,例如,讓SECURE_HSTS_SECONDS = 3600為一個小時。每當浏覽器在你的站點看到HSTS協定頭,都會在提供的時間段内絕對使用不安全(HTTP)的方式連接配接到你的域名。一旦你确認你站點上的所有東西都以安全的方式提供(例如,HSTS并不會幹擾任何事情),建議你增加這個值,這樣不常通路你站點的遊客也會被保護(比如,一般設定為31536000秒,一年)。

另外,如果你将 SECURE_HSTS_INCLUDE_SUBDOMAINS設定為True,,SecurityMiddleware會将includeSubDomains标簽添加到Strict-Transport-Security協定頭中。強烈推薦這樣做(假設所有子域完全使用HTTPS),否則你的站點仍舊有可能由于子域的不安全連接配接而受到攻擊。

HSTS政策在你的整個域中都被應用,不僅僅是你所設定協定頭的響應中的url。是以,如果你的整個域都設定為HTTPS only,你應該隻使用HSTS政策。

适當遵循HSTS協定頭的浏覽器,會通過顯示警告的方式,拒絕讓使用者連接配接到證書過期的、自行簽署的、或者其他SSL證書無效的站點。如果你使用了HSTS,確定你的證書處于一直有效的狀态!

注意

如果你的站點部署在負載均衡器或者反向代理之後,并且Strict-Transport-Security協定頭沒有添加到你的響應中,原因是Django有可能意識不到這是一個安全連接配接。你可能需要設定SECURE_PROXY_SSL_HEADER。

X-Content-Type-Options: nosniff

一些浏覽器會嘗試猜測他們所得内容的類型,而不是讀取Content-Type協定頭。雖然這樣有助于配置不當的伺服器正常顯示内容,但也會導緻安全問題。

如果你的站點允許使用者上傳檔案,一些惡意的使用者可能會上傳一個精心構造的檔案,當你覺得它無害的時候,檔案會被浏覽器解釋成HTML或者Javascript。

欲知更多有關這個協定頭和浏覽器如何處理它的内容,你可以在IE安全部落格中讀到它。

要防止浏覽器猜測内容類型,并且強制它一直使用 Content-Type協定頭中提供的類型,你可以傳遞X-Content-Type-Options: nosniff協定頭。SecurityMiddleware将會對所有響應這樣做,如果SECURE_CONTENT_TYPE_NOSNIFF 設定為True。

注意在大多數Django不涉及處理上傳檔案的部署環境中,這個設定不會有任何幫助。例如,如果你的MEDIA_URL被前端web伺服器直接處理(例如nginx和Apache),你可能想要在那裡設定這個協定頭。而在另一方面,如果你使用Django執行為了下載下傳檔案而請求授權之類的事情,并且你不能使用你的web伺服器設定協定頭,這個設定會很有用。

X-XSS-Protection: 1; mode=block

一些浏覽器能夠屏蔽掉出現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重定向

如果你同時提供HTTP和HTTPS連接配接,大多數使用者會預設使用不安全的(HTTP)連結。為了更高的安全性,你應該講所有HTTP連接配接重定向到HTTP連接配接。

如果你将SECURE_SSL_REDIRECT設定為True,SecurityMiddleware會将HTTP連結永久地(HTTP 301,permanently)重定向到HTTPS連接配接。

由于性能因素,最好在Django外面執行這些重定向,在nginx這種前端負載均衡器或者反向代理伺服器中執行。SECURE_SSL_REDIRECT專門為這種部署情況而設計,當這不可選擇的時候。

如果SECURE_SSL_HOST設定有一個值,所有重定向都會發到值中的主機,而不是原始的請求主機。

如果你站點上的一些頁面應該以HTTP方式提供,并且不需要重定向到HTTPS,你可以SECURE_REDIRECT_EXEMPT設定中列出比對那些url的正規表達式。

如果你在負載均衡器或者反向代理伺服器後面部署應用,而且Django不能辨識出什麼時候一個請求是安全的,你可能需要設定SECURE_PROXY_SSL_HEADER。

會話中間件

class SessionMiddleware[source]

開啟會話支援。詳見會話文檔。

站點中間件

class CurrentSiteMiddleware[source]

Django 1.7中新增           

向每個接收到的HttpRequest對象添加一個site屬性,表示目前的站點。詳見站點文檔。

認證中間件

class AuthenticationMiddleware[source]

向每個接收到的HttpRequest對象添加user屬性,表示目前登入的使用者。詳見web請求中的認證。

class RemoteUserMiddleware[source]

使用web伺服器提供認證的中間件。詳見使用REMOTE_USER進行認證。

class SessionAuthenticationMiddleware[source]

Django 1.7中新增           

當使用者修改密碼的時候使使用者的會話失效。詳見密碼更改時的會話失效。在MIDDLEWARE_CLASSES中,這個中間件必須出現在django.contrib.auth.middleware.AuthenticationMiddleware之後。

CSRF保護中間件

class CsrfViewMiddleware[source]

添加跨站點請求僞造的保護,通過向POST表單添加一個隐藏的表單字段,并檢查請求中是否有正确的值。詳見CSRF保護文檔。

X-Frame-Options中間件

class XFrameOptionsMiddleware[source]

通過X-Frame-Options協定頭進行簡單的點選劫持保護。

中間件的排序

下面是一些關于Django中間件排序的提示。

UpdateCacheMiddleware

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

GZipMiddleware

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

放在UpdateCacheMiddleware之後:會修改大量的協定頭。

ConditionalGetMiddleware

放在CommonMiddleware之前:當USE_ETAGS = True時會使用它的Etag 協定頭。

SessionMiddleware

放在UpdateCacheMiddleware之後:會修改 大量協定頭。

LocaleMiddleware

放在SessionMiddleware(由于使用會話資料)和 CacheMiddleware(由于要修改大量協定頭)之後的最上面。

CommonMiddleware

放在任何可能修改相應的中間件之前(因為它會生成ETags)。

在GZipMiddleware之後,不會在壓縮後的内容上再去生成ETag。

盡可能放在靠上面的位置,因為APPEND_SLASH或者PREPEND_WWW設定為 True時會被重定向。

CsrfViewMiddleware

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

AuthenticationMiddleware

放在SessionMiddleware之後:因為它使用會話存儲。

MessageMiddleware

放在SessionMiddleware之後:會使用基于會話的存儲。

FetchFromCacheMiddleware

放在任何修改大量協定頭的中間件之後:協定頭被用來從緩存的哈希表中擷取值。

FlatpageFallbackMiddleware

應該放在最底下,因為他是中間件中的底牌。

RedirectFallbackMiddleware