django中間件及自定義中間件的實(shí)現(xiàn)方法
middleware
中間件就是在目標(biāo)和結(jié)果之間進(jìn)行的額外處理過程,在Django中就是request和response之間進(jìn)行的處理,相對(duì)來說實(shí)現(xiàn)起來比較簡(jiǎn)單,但是要注意它是對(duì)全局有效的,可以在全局范圍內(nèi)改變輸入和輸出結(jié)果,因此需要謹(jǐn)慎使用,否則不僅會(huì)造成難以定位的錯(cuò)誤,而且可能會(huì)影響整體性能。
中間件有什么用
如果想要修改HttpRequest或者HttpResponse,就可以通過中間件來實(shí)現(xiàn)。
- 登陸認(rèn)證:在中間件中加入登陸認(rèn)證,所有請(qǐng)求就自動(dòng)擁有登陸認(rèn)證,如果需要放開部分路由,只需要特殊處理就可以了。
- 流量統(tǒng)計(jì):可以針對(duì)一些渲染頁面統(tǒng)計(jì)訪問流量。
- 惡意請(qǐng)求攔截:統(tǒng)計(jì)IP請(qǐng)求次數(shù),可以進(jìn)行頻次限制或者封禁IP。
本身django項(xiàng)目就帶有很多的中間件,在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請(qǐng)求發(fā)起的時(shí)候,就需要先注釋掉csrf那一個(gè)中間件。
每個(gè)中間件的功能如下,
SecurityMiddleware
:為request/response提供了幾種安全改進(jìn);SessionMiddleware
:開啟session會(huì)話支持;CommonMiddleware
:基于APPEND_SLASH和PREPEND_WWW的設(shè)置來重寫URL,如果APPEND_SLASH設(shè)為True,并且初始URL 沒有以斜線結(jié)尾以及在URLconf 中沒找到對(duì)應(yīng)定義,這時(shí)形成一個(gè)斜線結(jié)尾的新URL;CsrfViewMiddleware
:添加跨站點(diǎn)請(qǐng)求偽造的保護(hù),通過向POST表單添加一個(gè)隱藏的表單字段,并檢查請(qǐng)求中是否有正確的值;AuthenticationMiddleware
:在視圖函數(shù)執(zhí)行前向每個(gè)接收到的user對(duì)象添加HttpRequest屬性,表示當(dāng)前登錄的用戶,無它用不了request.user
。MessageMiddleware
:開啟基于Cookie和會(huì)話的消息支持XFrameOptionsMiddleware
:對(duì)點(diǎn)擊劫持的保護(hù)
除此以外, Django還提供了壓縮網(wǎng)站內(nèi)容的GZipMiddleware
,根據(jù)用戶請(qǐng)求語言返回不同內(nèi)容的LocaleMiddleware
和給GET請(qǐng)求附加條件的ConditionalGetMiddleware
。這些中間件都是可選的。
Django的中間件執(zhí)行順序
當(dāng)你在settings.py
注冊(cè)中間件時(shí)一定要要考慮中間件的執(zhí)行順序,中間件在request到達(dá)view之前是從上向下執(zhí)行的,在view執(zhí)行完后返回response過程中是從下向上執(zhí)行的,如下圖所示。舉個(gè)例子,如果你自定義的中間件有依賴于request.user
,那么你自定義的中間件一定要放在AuthenticationMiddleware
的后面
工作原理
HTTP Web服務(wù)器工作原理一般都是接收用戶發(fā)來的請(qǐng)求(request), 然后給出響應(yīng)(response)。Django也不例外,其一般工作方式是接收request對(duì)象和其它參數(shù),交由視圖(view)處理,然后給出它的響應(yīng)(respone)數(shù)據(jù): 渲染過的html文件或json格式的數(shù)據(jù)。然而在實(shí)際工作中Django并不是接收到request對(duì)象后,馬上交給視圖函數(shù)或類(view)處理,也不是在view執(zhí)行后立馬給用戶返回reponse。事實(shí)上Django最初接收的是HttpRequest對(duì)象,而不是request對(duì)象,正是中間件的作用把HttpRequest對(duì)象和user對(duì)象打包成了一個(gè)全局變量request對(duì)象,這樣你才可以View中使用request作為變量或者在模板中隨意調(diào)用request.user。
中間件(Middleware)在整個(gè)Django的request/response處理機(jī)制中的角色如下所示:
HttpRequest -> Middleware -> View -> Middleware -> HttpResponse
正是由于一個(gè)請(qǐng)求HttpRequest在傳遞給視圖View處理前要經(jīng)過中間件處理,經(jīng)過View處理后的響應(yīng)也要經(jīng)過中間件處理才能返回給用戶,我們可以編寫自己的中間件實(shí)現(xiàn)權(quán)限校驗(yàn),限制用戶請(qǐng)求、打印日志、改變輸出內(nèi)容等多種應(yīng)用場(chǎng)景,比如:
- 禁止特定IP地址的用戶或未登錄的用戶訪問我們的View視圖函數(shù)
- 對(duì)同一IP地址單位時(shí)間內(nèi)發(fā)送的請(qǐng)求數(shù)量做出限制
- 在View視圖函數(shù)執(zhí)行前記錄用戶的IP地址
- 在View視圖函數(shù)執(zhí)行前傳遞額外的變量或參數(shù)
- 在View視圖函數(shù)執(zhí)行前或執(zhí)行后把特定信息打印到log日志
- 在View視圖函數(shù)執(zhí)行后對(duì)reponse數(shù)據(jù)進(jìn)行修改后返回給用戶
值得一提的是中間件對(duì)Django的輸入或輸出的改變是全局的,反之亦然。如果讓你希望對(duì)Django的輸入或輸出做出全局性的改變時(shí),需要使用中間件。舉個(gè)例子,我們?cè)谘b飾器一文中介紹了如何使用@login_required裝飾器要求用戶必須先登錄才能訪問我們的視圖函數(shù)。試想我們有個(gè)網(wǎng)站絕大部分視圖函數(shù)都需要用戶登錄,每個(gè)視圖函數(shù)前面都需要加上@login_required裝飾器是比較傻的行為。借助于中間件,我們無需使用裝飾器即可全局實(shí)現(xiàn):只有登錄用戶才能訪問視圖函數(shù),匿名用戶跳轉(zhuǎn)到登錄頁面。實(shí)現(xiàn)原理也很簡(jiǎn)單,在一個(gè)request到達(dá)視圖函數(shù)前,我們先對(duì)request.user是否驗(yàn)證通過進(jìn)行判斷,然后再進(jìn)行跳轉(zhuǎn)。另外Django對(duì)POST表單中攜帶的CSRF token的全局校驗(yàn)也是通過CsrfViewMiddleware這個(gè)中間件進(jìn)行的,而不是通過單個(gè)裝飾器實(shí)現(xiàn)的。
自定義中間件
一般的中間件必須要有的兩個(gè)函數(shù)就是process_request
和process_response
如果自己定義中間件,首先在app里創(chuàng)建一個(gè)py文件,然后導(dǎo)入一些自帶的模塊
然后就是自定義類
class ReginaMiddleWare(MiddlewareMixin): def process_request(self,request): ''' :param request: 請(qǐng)求信息對(duì)象 :return: ''' print("reginaMiddleWare",request) def process_response(self,response,request): ''' :param response: 請(qǐng)求信息對(duì)象 :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返回的不是默認(rèn)的None,則表示攔截成功,那么也不會(huì)經(jīng)過IvanleeMiddleware,直接回到ReginaMiddleware的響應(yīng)處原路返回
process_response
def process_response(self,response,request): ''' :param response: 請(qǐng)求信息對(duì)象 :param request: 視圖函數(shù)返回的響應(yīng)體 :return: ''' print("ivanleeMiddleWare_response") response.content = response.content + b"<h1>I love Regina</h1>" //必須是用b去定義轉(zhuǎn)義類型 return response
那么在返回的時(shí)候,響應(yīng)內(nèi)容就是原有的helloworld和IloveRegina一起發(fā)送給請(qǐng)求者。
到此這篇關(guān)于django中間件及自定義中間件的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)django自定義中間件 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解在OpenCV中實(shí)現(xiàn)的圖像標(biāo)注技術(shù)
圖像標(biāo)注在計(jì)算機(jī)視覺中很重要,計(jì)算機(jī)視覺是一種技術(shù),它允許計(jì)算機(jī)從數(shù)字圖像或視頻中獲得高水平的理解力,并以人類的方式觀察和解釋視覺信息,本文將重點(diǎn)討論在OpenCV的幫助下創(chuàng)建這些注釋,感興趣的朋友一起看看吧2022-06-06Python使用SQLAlchemy模塊實(shí)現(xiàn)操作數(shù)據(jù)庫
SQLAlchemy 是用Python編程語言開發(fā)的一個(gè)開源項(xiàng)目,它提供了SQL工具包和ORM對(duì)象關(guān)系映射工具,使用SQLAlchemy可以實(shí)現(xiàn)高效和高性能的數(shù)據(jù)庫訪問,下面我們就來學(xué)習(xí)一下SQLAlchemy模塊的具體應(yīng)用吧2023-11-11Django使用HTTP協(xié)議向服務(wù)器傳參方式小結(jié)
本文主要介紹了Django使用HTTP協(xié)議向服務(wù)器傳參方式小結(jié),用戶發(fā)送請(qǐng)求時(shí)攜帶的參數(shù)后端需要使用,而不同的發(fā)送參數(shù)的方式對(duì)應(yīng)了不同的提取參數(shù)的方式,本文就詳細(xì)的介紹一下2021-08-08python調(diào)用opencv實(shí)現(xiàn)貓臉檢測(cè)功能
這篇文章主要介紹了python調(diào)用opencv實(shí)現(xiàn)貓臉檢測(cè)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Python爬取門戶論壇評(píng)論淺談Python未來發(fā)展方向
這篇文章主要介紹了如何實(shí)現(xiàn)Python爬取門戶論壇評(píng)論,附含圖片示例代碼,講解了詳細(xì)的操作過程,有需要的的朋友可以借鑒參考下,希望可以有所幫助2021-09-09Python簡(jiǎn)單獲取網(wǎng)卡名稱及其IP地址的方法【基于psutil模塊】
這篇文章主要介紹了Python簡(jiǎn)單獲取網(wǎng)卡名稱及其IP地址的方法,結(jié)合實(shí)例形式分析了Python基于psutil模塊針對(duì)本機(jī)網(wǎng)卡硬件信息的讀取操作簡(jiǎn)單使用技巧,需要的朋友可以參考下2018-05-05python類的方法屬性與方法屬性的動(dòng)態(tài)綁定代碼詳解
這篇文章主要介紹了python類的方法屬性與方法屬性的動(dòng)態(tài)綁定代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下2017-12-12