欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

django中間件及自定義中間件的實現(xiàn)方法

 更新時間:2023年06月19日 09:21:52   作者:ivanlee717  
中間件就是在目標和結(jié)果之間進行的額外處理過程,在Django中就是request和response之間進行的處理,相對來說實現(xiàn)起來比較簡單,這篇文章主要介紹了django中間件以及自定義中間件?,需要的朋友可以參考下

middleware

中間件就是在目標結(jié)果之間進行的額外處理過程,在Django中就是request和response之間進行的處理,相對來說實現(xiàn)起來比較簡單,但是要注意它是對全局有效的,可以在全局范圍內(nèi)改變輸入和輸出結(jié)果,因此需要謹慎使用,否則不僅會造成難以定位的錯誤,而且可能會影響整體性能。

中間件有什么用

如果想要修改HttpRequest或者HttpResponse,就可以通過中間件來實現(xiàn)。

  • 登陸認證:在中間件中加入登陸認證,所有請求就自動擁有登陸認證,如果需要放開部分路由,只需要特殊處理就可以了。
  • 流量統(tǒng)計:可以針對一些渲染頁面統(tǒng)計訪問流量。
  • 惡意請求攔截:統(tǒng)計IP請求次數(shù),可以進行頻次限制或者封禁IP。

本身django項目就帶有很多的中間件,在setting.py

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',
]

之前我們通過post請求發(fā)起的時候,就需要先注釋掉csrf那一個中間件。

每個中間件的功能如下,

  • SecurityMiddleware:為request/response提供了幾種安全改進;
  • SessionMiddleware:開啟session會話支持;
  • CommonMiddleware:基于APPEND_SLASH和PREPEND_WWW的設(shè)置來重寫URL,如果APPEND_SLASH設(shè)為True,并且初始URL 沒有以斜線結(jié)尾以及在URLconf 中沒找到對應(yīng)定義,這時形成一個斜線結(jié)尾的新URL;
  • CsrfViewMiddleware:添加跨站點請求偽造的保護,通過向POST表單添加一個隱藏的表單字段,并檢查請求中是否有正確的值;
  • AuthenticationMiddleware:在視圖函數(shù)執(zhí)行前向每個接收到的user對象添加HttpRequest屬性,表示當(dāng)前登錄的用戶,無它用不了request.user
  • MessageMiddleware:開啟基于Cookie和會話的消息支持
  • XFrameOptionsMiddleware:對點擊劫持的保護

除此以外, Django還提供了壓縮網(wǎng)站內(nèi)容的GZipMiddleware,根據(jù)用戶請求語言返回不同內(nèi)容的LocaleMiddleware和給GET請求附加條件的ConditionalGetMiddleware。這些中間件都是可選的。

Django的中間件執(zhí)行順序

當(dāng)你在settings.py注冊中間件時一定要要考慮中間件的執(zhí)行順序,中間件在request到達view之前是從上向下執(zhí)行的,在view執(zhí)行完后返回response過程中是從下向上執(zhí)行的,如下圖所示。舉個例子,如果你自定義的中間件有依賴于request.user,那么你自定義的中間件一定要放在AuthenticationMiddleware的后面

工作原理

HTTP Web服務(wù)器工作原理一般都是接收用戶發(fā)來的請求(request), 然后給出響應(yīng)(response)。Django也不例外,其一般工作方式是接收request對象和其它參數(shù),交由視圖(view)處理,然后給出它的響應(yīng)(respone)數(shù)據(jù): 渲染過的html文件或json格式的數(shù)據(jù)。然而在實際工作中Django并不是接收到request對象后,馬上交給視圖函數(shù)或類(view)處理,也不是在view執(zhí)行后立馬給用戶返回reponse。事實上Django最初接收的是HttpRequest對象,而不是request對象,正是中間件的作用把HttpRequest對象和user對象打包成了一個全局變量request對象,這樣你才可以View中使用request作為變量或者在模板中隨意調(diào)用request.user。

中間件(Middleware)在整個Django的request/response處理機制中的角色如下所示:

HttpRequest -> Middleware -> View -> Middleware -> HttpResponse

正是由于一個請求HttpRequest在傳遞給視圖View處理前要經(jīng)過中間件處理,經(jīng)過View處理后的響應(yīng)也要經(jīng)過中間件處理才能返回給用戶,我們可以編寫自己的中間件實現(xiàn)權(quán)限校驗,限制用戶請求、打印日志、改變輸出內(nèi)容等多種應(yīng)用場景,比如:

  • 禁止特定IP地址的用戶或未登錄的用戶訪問我們的View視圖函數(shù)
  • 對同一IP地址單位時間內(nèi)發(fā)送的請求數(shù)量做出限制
  • 在View視圖函數(shù)執(zhí)行前記錄用戶的IP地址
  • 在View視圖函數(shù)執(zhí)行前傳遞額外的變量或參數(shù)
  • 在View視圖函數(shù)執(zhí)行前或執(zhí)行后把特定信息打印到log日志
  • 在View視圖函數(shù)執(zhí)行后對reponse數(shù)據(jù)進行修改后返回給用戶

值得一提的是中間件對Django的輸入或輸出的改變是全局的,反之亦然。如果讓你希望對Django的輸入或輸出做出全局性的改變時,需要使用中間件。舉個例子,我們在裝飾器一文中介紹了如何使用@login_required裝飾器要求用戶必須先登錄才能訪問我們的視圖函數(shù)。試想我們有個網(wǎng)站絕大部分視圖函數(shù)都需要用戶登錄,每個視圖函數(shù)前面都需要加上@login_required裝飾器是比較傻的行為。借助于中間件,我們無需使用裝飾器即可全局實現(xiàn):只有登錄用戶才能訪問視圖函數(shù),匿名用戶跳轉(zhuǎn)到登錄頁面。實現(xiàn)原理也很簡單,在一個request到達視圖函數(shù)前,我們先對request.user是否驗證通過進行判斷,然后再進行跳轉(zhuǎn)。另外Django對POST表單中攜帶的CSRF token的全局校驗也是通過CsrfViewMiddleware這個中間件進行的,而不是通過單個裝飾器實現(xiàn)的。

自定義中間件

一般的中間件必須要有的兩個函數(shù)就是process_requestprocess_response

如果自己定義中間件,首先在app里創(chuàng)建一個py文件,然后導(dǎo)入一些自帶的模塊

然后就是自定義類

class ReginaMiddleWare(MiddlewareMixin):
    def process_request(self,request):
        '''
        :param request: 請求信息對象
        :return:
        '''
        print("reginaMiddleWare",request)
    def process_response(self,response,request):
        '''
        :param response: 請求信息對象
        :param request: 視圖函數(shù)返回的響應(yīng)體
        :return:
        '''
        print(response)
        return response

第三步就是把自己寫好的中間件按照目錄位置添加到settings文件當(dāng)中

MIDDLEWARE = [
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'reginauser.reginaMiddleware.ReginaMiddleWare',
    'reginauser.reginaMiddleware.IvanleeMiddleWare'
]

process_request功能

ip = request.META.get("REMOTE_ADDR")
if ip in ['127.0.0.1','']:
  return HttpResponse("非法ip")

我們可以試一下本地地址,一旦process_request返回的不是默認的None,則表示攔截成功,那么也不會經(jīng)過IvanleeMiddleware,直接回到ReginaMiddleware的響應(yīng)處原路返回

process_response

    def process_response(self,response,request):
        '''
        :param response: 請求信息對象
        :param request: 視圖函數(shù)返回的響應(yīng)體
        :return:
        '''
        print("ivanleeMiddleWare_response")
        response.content = response.content + b"<h1>I love Regina</h1>"  //必須是用b去定義轉(zhuǎn)義類型
        return response

那么在返回的時候,響應(yīng)內(nèi)容就是原有的helloworld和IloveRegina一起發(fā)送給請求者。

到此這篇關(guān)于django中間件及自定義中間件的實現(xiàn)方法的文章就介紹到這了,更多相關(guān)django自定義中間件 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論