目錄
一、引入
二、Django中間件介紹
【1】什么是Django中間件
【2】Django中間件的作用
【3】示例
三、Django請求生命周期流程圖
四、Django中間件是Django的門戶
五、Django中間件詳解
六、中間件必須要掌握的兩個方法
(1)? process_request
(2)? process_response
七、自定義中間件
【1】process_request
【2】process_response
【3】小結
一、引入
- Django自帶七個中間件,每個中間件都有各自對應的功能
- 并且Django支持用戶自定義中間件
- 在使用Django框架開發項目的時候,只要是涉及到全局相關的功能都可以使用中間件更加方便的完成
- 比如全局身份校驗
- 全局用戶權限校驗
- 全局訪問頻率的校驗
- ...
二、Django中間件介紹
【1】什么是Django中間件
- Django中間件是一個輕量級、可重用的組件,用于處理Django請求和響應的過程。
- 它提供了對請求和響應進行全局處理的機制,可以在請求達到視圖之前進行預處理或在響應返回給客戶端之前進行后處理。
- 中間件是按照順序依次執行的,每個中間件都可以對請求和響應進行修改、補充或處理。
- 在Django的settings.py配置文件中,通過MIDDLEWARE設置來定義中間件的順序。
【2】Django中間件的作用
- 認證和授權:
- 中間件可以在請求到達視圖之前進行用戶認證和權限驗證,確保只有經過授權的用戶才能訪問敏感資源。
- 請求和響應處理:
- 中間件可以在請求到達視圖之前對請求進行預處理
- 例如添加請求頭信息、檢查請求參數的合法性等操作。
- 同時,在視圖函數返回響應給客戶端之前,中間件還可以對響應進行后處理
- 例如添加額外的響應頭、包裝響應數據等操作。
- 中間件可以在請求到達視圖之前對請求進行預處理
- 異常處理:
- 中間件還可以捕獲視圖函數中可能拋出的異常,并做相應的處理
- 例如記錄異常日志、返回自定義錯誤信息等。
- 中間件還可以捕獲視圖函數中可能拋出的異常,并做相應的處理
- 性能優化:
- 通過中間件,可以對請求進行性能監測、緩存處理、壓縮響應等操作,提升網站的整體性能。
【3】示例
class MyMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 在視圖函數調用之前的預處理邏輯# ...response = self.get_response(request)# 在響應返回給客戶端之前的后處理邏輯# ...return response
三、Django請求生命周期流程圖
- 當客戶端發送一個請求到Django應用程序時,Django會按照一定的生命周期流程處理該請求。
- 客戶端發出HTTP請求。
- 請求被Web服務器接收并傳遞給Django應用程序。
- Django中的WSGI中間件開始處理請求,并可進行一些預處理操作。
- 中間件將請求傳遞給URL分發器(URL Dispatcher)。
- URL分發器根據URL模式將請求路由到相應的視圖函數或處理器(View/Handler)。
- 視圖函數或處理器執行相應的業務邏輯,可能會與數據庫等外部資源交互。
- 視圖函數或處理器返回一個HTTP響應對象。
- 響應對象經過中間件,可以在此進行后處理操作。
- 響應被發送給Web服務器。
- Web服務器將響應發送回客戶端。
四、Django中間件是Django的門戶
- 請求發來的時候需要先經過中間件才能到達真正的Django后端
- 響應返回的時候,最后也需要進過中間件返回發送出去
五、Django中間件詳解
(1)? SecurityMiddleware
- django.middleware.security.SecurityMiddleware:
- 安全中間件負責處理與網站安全相關的任務
- 例如設置HTTP頭部,防止跨站腳本攻擊(XSS),點擊劫持等。
- 它可以通過配置自定義安全策略來確保網站的安全性。
(2)? SessionMiddleware
- django.contrib.sessions.middleware.SessionMiddleware:
- 會話中間件負責處理用戶會話的創建之間存儲和檢索用戶數據。
- 它基于瀏覽器提供的Cookie或URL傳遞的會話ID進行會話跟蹤,并將會話數據存儲在后端數據庫或緩存中,以實現用戶狀態的跨請求保持。
(3)? CommonMiddleware
- django.middleware.common.CommonMiddleware:
- 通用中間件提供了一些常見而關鍵的HTTP請求處理功能
- 例如,根據請求的HTTP頭信息設置語言、時區等。
- 此外,它還處理靜態文件的serving,包括收集靜態文件,為其生成URL,并在開發模式下提供靜態文件的serving。
(4)? CsrfViewMiddleware
- django.middleware.csrf.CsrfViewMiddleware:
- CSRF(Cross-Site Request Forgery)中間件用于防止跨站請求偽造攻擊。
- 它在每個POST請求中驗證一個CSRF標記,確保請求是通過合法的表單提交得到的,從而保護用戶免受惡意站點的攻擊。
(5)? AuthenticationMiddleware
- django.contrib.auth.middleware.AuthenticationMiddleware:
- 認證中間件負責處理用戶身份認證相關的任務
- 例如將認證信息關聯到請求對象上,為每個請求提供一個user對象,以便在請求處理過程中輕松地獲取和使用用戶身份信息。
(6)? MessageMiddleware
- django.contrib.messages.middleware.MessageMiddleware:
- 消息中間件用于在請求處理過程中存儲和傳遞臨時的、一次性的用戶消息。
- 它允許在HTTP重定向之間跨請求傳遞消息,例如成功或錯誤提示,以改善用戶體驗。
(7)? XFrameOptionsMiddleware
- django.middleware.clickjacking.XFrameOptionsMiddleware:
- 點擊劫持中間件用于防止頁面被嵌入到其他網站中,從而提供一定的點擊劫持保護。
- 它通過設置X-Frame-Options HTTP頭部來限制頁面的顯示方式,從而防止惡意網頁通過iframe等方式嵌入當前網頁。
六、中間件必須要掌握的兩個方法
(1)? process_request
(1)執行順序
- 請求來的時候需要經過每一個中間件的 process_request 方法
- 結果的順序是按照配置文件中注冊的中間件從上往下的順序執行的
(2)沒有定義process_request
- 如果沒有定義這個方法,就跳過這個中間件
(3)定義了返回值
- 如果在自定義中間件中定義了返回值(三板斧),那么請求將不再繼續執行,而是直接原路返回(校驗失敗不允許訪問)
(4)總結
- process_request 方法就是用來 做全局相關的所有限制功能
- 該方法在每個請求到達視圖之前被調用,可以對請求進行預處理。
- 例如,進行身份驗證、訪問控制或請求日志記錄等操作。
- 它接收一個HttpRequest對象作為參數,并且沒有返回值
示例:
class AuthenticationMiddleware:def process_request(self, request):# 在這里進行身份驗證操作if not request.user.is_authenticated:# 如果用戶未經身份驗證,則返回HttpResponse或重定向到登錄頁面
(2)? process_response
- 響應被返回的時候需要結束每一個中間件里面的 process_response 方法
- 該方法有兩個額外的參數
- request
- response
- 該方法必須返回 HttpResponse 對象
- 默認是response
- 支持自定義
- 順序是按照配置文件中注冊過的中間件從下往上依次經過
- 如果沒有定義,則跳過,校驗下一個
- 該方法在每個請求結束并且響應返回到客戶端之前被調用。
- 可以在此處對響應進行處理
- 例如添加額外的頭信息、修改響應內容等。
- 它接收一個HttpRequest對象和HttpResponse對象作為參數,并且必須返回一個HttpResponse對象。
示例:
class CustomResponseMiddleware:def process_response(self, request, response):# 在這里對響應進行處理response['X-Custom-Header'] = 'Custom Value'return response
七、自定義中間件
【1】process_request
- 路由層
from app01 import viewsurlpatterns = [path('admin/', admin.site.urls),path('index/',views.index),
]
- 視圖層?
def index(request):print("這是視圖函數index")return HttpResponse("index 的返回值")
- 配置文件?
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',# 注冊自己的中間件(在應用下創建路徑會有提示,但是如果在項目下創建就沒有提示,需要自己根據路徑書寫)'app01.mymiddle.my_middle.MyMiddle',# 誰先注冊就先執行誰'app01.mymiddle.my_middle.MyMiddle2',
]
- 自定義中間件?
# 引入父類
from django.utils.deprecation import MiddlewareMixinclass MyMiddle(MiddlewareMixin):def process_request(self, request):print("這是第一個自定義中間件中的 process_request 方法")class MyMiddle2(MiddlewareMixin):def process_request(self, request):print("這是第二個自定義中間件中的 process_request 方法")
【2】process_response
# 引入父類
from django.utils.deprecation import MiddlewareMixinclass MyMiddle(MiddlewareMixin):def process_request(self, request):print("這是第一個自定義中間件中的 process_request 方法")def process_response(self, request, response):''':param request: :param response: 就是Django返回給瀏覽器的內容:return: '''print("這是第一個自定義中間件中的 process_response 方法")# 必須返回 responserreturn response
【3】小結
- 如果在第一個 process_request 方法就已經返回了 HttpResponse 對象,那么響應被返回的時候是經過所有的中間件里面的 process_response 方法還是會發生其他?
- 會直接走同級別的 process_response 方法 ,然后直接返回
- flask框架的中間件也有一個類似的方法
- 但是flask返回數據就必須經過所有中間件里面的 process_response 方法