最淺顯易懂的Django系列教程(40)-中間件

中間件

中間件是在requestresponse處理過程中的一個插件。比如在request到達(dá)視圖函數(shù)之前,我們可以使用中間件來做一些相關(guān)的事情,比如可以判斷當(dāng)前這個用戶有沒有登錄,如果登錄了,就綁定一個user對象到request上。也可以在response到達(dá)瀏覽器之前,做一些相關(guān)的處理,比如想要統(tǒng)一在response上設(shè)置一些cookie信息等。

自定義中間件:

中間件所處的位置沒有規(guī)定。只要是放到項(xiàng)目當(dāng)中即可。一般分為兩種情況,如果中間件是屬于某個app的,那么可以在這個app下面創(chuàng)建一個python文件用來存放這個中間件,也可以專門創(chuàng)建一個Python包,用來存放本項(xiàng)目的所有中間件。創(chuàng)建中間件有兩種方式,一種是使用函數(shù),一種是使用類,接下來對這兩種方式做個介紹:

使用函數(shù)的中間件:

def simple_middleware(get_response):
      # 這個中間件初始化的代碼

      def middleware(request):
          # request到達(dá)view的執(zhí)行代碼

          response = get_response(request)

          # response到達(dá)瀏覽器的執(zhí)行代碼

          return response

      return middleware

使用類的中間件:

class SimpleMiddleware(object):
      def __init__(self, get_response):
          self.get_response = get_response
          # 這個中間件初始化的代碼
          def __call__(self, request):
              # request到達(dá)view之前執(zhí)行的代碼

              response = self.get_response(request)

              # response到達(dá)用戶瀏覽器之前執(zhí)行的代碼

              return response

在寫完中間件后,還需要在settings.MIDDLEWARES中配置寫好的中間件才可以使用。比如我們寫了一個在request到達(dá)視圖函數(shù)之前,判斷這個用戶是否登錄,如果已經(jīng)登錄就綁定一個user對象到request上的中間件,這個中間件放在當(dāng)前項(xiàng)目的middlewares.users下:

def user_middleware(get_response):
      # 這個中間件初始化的代碼

      def middleware(request):
          # request到達(dá)view的執(zhí)行代碼
          userid = request.session.get("userid")
          userModel = FrontUser.objects.filter(pk=userid).first()
          if userModel:
                  setattr(request,'frontuser',userModel)

          response = get_response(request)

          # response到達(dá)瀏覽器的執(zhí)行代碼

          return response

      return middleware

那么就可以在settings.MIDDLEWARES下做以下配置:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'middlewares.users.user_middleware'
]

中間件的執(zhí)行是有順序的,他會根據(jù)在MIDDLEWARE中存放的順序來執(zhí)行。因此如果有些中間件是需要基于其他中間件的,那么就需要放在其他中間件的后面來執(zhí)行。

Django內(nèi)置的中間件:

  1. django.middleware.common.CommonMiddleware:通用中間件。他的作用如下:
    • 限制settings.DISALLOWED_USER_AGENTS中指定的請求頭來訪問本網(wǎng)站。DISALLOWED_USER_AGENT是一個正則表達(dá)式的列表。示例代碼如下:
            import re
            DISALLOWED_USER_AGENTS = [
                re.compile(r'^\s$|^$'),
                re.compile(r'.*PhantomJS.*')
            ]
      
    • 如果開發(fā)者在定義url的時候,最后有一個斜杠。但是用戶在訪問url的時候沒有提交這個斜杠,那么CommonMiddleware會自動的重定向到加了斜杠的url上去。
  2. django.middleware.gzip.GZipMiddleware:將響應(yīng)數(shù)據(jù)進(jìn)行壓縮。如果內(nèi)容長度少于200個長度,那么就不會壓縮。
  3. django.contrib.messages.middleware.MessageMiddleware:消息處理相關(guān)的中間件。
  4. django.middleware.security.SecurityMiddleware:做了一些安全處理的中間件。比如設(shè)置XSS防御的請求頭,比如做了http協(xié)議轉(zhuǎn)https協(xié)議的工作等。
  5. django.contrib.sessions.middleware.SessionMiddlewaresession中間件。會給request添加一個處理好的session對象。
  6. django.contrib.auth.middleware.AuthenticationMiddleware:會給request添加一個user對象的中間件。
  7. django.middleware.csrf.CsrfViewMiddlewareCSRF保護(hù)的中間件。
  8. django.middleware.clickjacking.XFrameOptionsMiddleware:做了clickjacking攻擊的保護(hù)。clickjacking保護(hù)是攻擊者在自己的病毒網(wǎng)站上,寫一個誘惑用戶點(diǎn)擊的按鈕,然后使用iframe的方式將受攻擊的網(wǎng)站(比如銀行網(wǎng)站)加載到自己的網(wǎng)站上去,并將其設(shè)置為透明的,用戶就看不到,然后再把受攻擊的網(wǎng)站(比如銀行網(wǎng)站)的轉(zhuǎn)賬按鈕定位到病毒網(wǎng)站的按鈕上,這樣用戶在點(diǎn)擊病毒網(wǎng)站上按鈕的時候,實(shí)際上點(diǎn)擊的是受攻擊的網(wǎng)站(比如銀行網(wǎng)站)上的按鈕,從而實(shí)現(xiàn)了在不知不覺中給攻擊者轉(zhuǎn)賬的功能。
  9. 緩存中間件:用來緩存一些頁面的。
    • django.middleware.cache.UpdateCacheMiddleware。
    • django.middleware.cache.FetchFromCacheMiddleware。

內(nèi)置中間件放置的順序:

  1. SecurityMiddleware:應(yīng)該放到最前面。因?yàn)檫@個中間件并不需要依賴任何其他的中間件。如果你的網(wǎng)站同時支持http協(xié)議和https協(xié)議,并且你想讓用戶在使用http協(xié)議的時候重定向到https協(xié)議,那么就沒有必要讓他執(zhí)行下面一大串中間件再重定向,這樣效率更高。
  2. UpdateCacheMiddleware:應(yīng)該在SessionMiddleware, GZipMiddleware, LocaleMiddleware之前。
  3. GZipMiddleware
  4. ConditionalGetMiddleware。
  5. SessionMiddleware
  6. LocaleMiddleware。
  7. CommonMiddleware。
  8. CsrfViewMiddleware
  9. AuthenticationMiddleware。
  10. MessageMiddleware
  11. FetchFromCacheMiddleware。
  12. FlatpageFallbackMiddleware。
  13. RedirectFallbackMiddleware

看文章不過癮?還有免費(fèi)的視頻教程,讓你學(xué)起來更輕松:https://www.zhiliaoketang.cn/course/detail/4.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容