Django內置的中間件說明

可用的中間件

緩存中間件

class UpdateCacheMiddlewarehtml

class FetchFromCacheMiddleware前端

開啓全站範圍的緩存。 若是開啓了這些緩存,任何一個由Django提供的頁面將會被緩存,緩存時長是由你在CACHE_MIDDLEWARE_SECONDS配置中定義的。python

「通用」的中間件

class CommonMiddlewarenginx

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

  • 禁止訪問DISALLOWED_USER_AGENTS中設置的用戶代理,這項配置應該是一個已編譯的正則表達式對象的列表。正則表達式

  • 基於APPEND_SLASH和PREPEND_WWW的設置來重寫URL。django

    若是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

New in Django 1.8.

默認爲HttpResponsePermanentRedirect。它繼承了CommonMiddleware,並覆寫了屬性來自定義中間件發出的重定向。

class BrokenLinkEmailsMiddleware

  • MANAGERS發送死鏈提醒郵件。

GZip中間件

class GZipMiddleware

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

爲支持GZip壓縮的瀏覽器(一些現代的瀏覽器)壓縮內容。

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

若是知足下面條件的話,內容不會被壓縮:

  • 消息體的長度小於200個字節。
  • 響應已經設置了Content-Encoding協議頭。
  • 請求(瀏覽器)沒有發送包含gzip的Accept-Encoding協議頭。

你能夠經過這個gzip_page()裝飾器使用獨立的GZip壓縮。

帶條件判斷的GET中間件

class ConditionalGetMiddleware

處理帶有條件判斷狀態GET操做。 若是一個請求包含 ETag 或者Last-Modified協議頭,而且請求包含If-None-Match或If-Modified-Since,這時響應會被 替換爲HttpResponseNotModified。

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

地域性中間件

class LocaleMiddleware

基於請求中的數據開啓語言選擇。 它能夠爲每一個用戶進行定製。。

LocaleMiddleware.response_redirect_class

默認爲HttpResponseRedirect。繼承自LocaleMiddleware並覆寫了屬性來自定義中間件發出的重定向。

消息中間件

class MessageMiddleware

開啓基於Cookie和會話的消息支持。

安全中間件

警告

若是你的部署環境容許的話,讓你的前端web服務器展現SecurityMiddleware提供的功能是個好主意。這樣一來,若是有任何請求沒有被Django處理(好比靜態媒體或用戶上傳的文件),它們會擁有和向Django 應用的請求相同的保護。

class SecurityMiddleware

New in 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 鏈接到HTTPS。

若是你將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

開啓會話支持。

站點中間件

class CurrentSiteMiddleware

向每一個接收到的HttpRequest對象添加一個site屬性,表示當前的站點。

認證中間件

class AuthenticationMiddleware

向每一個接收到的HttpRequest對象添加user屬性,表示當前登陸的用戶。

class RemoteUserMiddleware

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

class SessionAuthenticationMiddleware

當用戶修改密碼的時候使用戶的會話失效。在MIDDLEWARE_CLASSES中,這個中間件必須出如今django.contrib.auth.middleware.AuthenticationMiddleware以後。

CSRF保護中間件

class CsrfViewMiddleware

添加跨站點請求僞造的保護,經過向POST表單添加一個隱藏的表單字段,並檢查請求中是否有正確的值。

X-Frame-Options中間件

class XFrameOptionsMiddleware

經過X-Frame-Options協議頭進行簡單的點擊劫持保護

中間件的排序

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

  1. UpdateCacheMiddleware

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

  2. GZipMiddleware

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

    放在UpdateCacheMiddleware以後:會修改大量的協議頭。

  3. ConditionalGetMiddleware

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

  4. SessionMiddleware

    放在UpdateCacheMiddleware以後:會修改 大量協議頭。

  5. LocaleMiddleware

    放在SessionMiddleware(因爲使用會話數據)和 CacheMiddleware(因爲要修改大量協議頭)以後的最上面。

  6. CommonMiddleware

    放在任何可能修改相應的中間件以前(由於它會生成ETags)。

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

    儘量放在靠上面的位置,由於APPEND_SLASH或者PREPEND_WWW設置爲 True時會被重定向。

  7. CsrfViewMiddleware

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

  8. AuthenticationMiddleware

    放在SessionMiddleware以後:由於它使用會話存儲。

  9. MessageMiddleware

    放在SessionMiddleware以後:會使用基於會話的存儲。

  10. FetchFromCacheMiddleware

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

  11. FlatpageFallbackMiddleware

    應該放在最底下,由於它是中間件中的最後一手。

  12. RedirectFallbackMiddleware

    應該放在最底下,由於它是中間件中的最後一手。

相關文章
相關標籤/搜索