中間件前端
1、什麼是中間件web
請求的時候須要先通過中間件才能到達django後端(urls,views,templates,models)ajax
響應的時候也須要通過中間件才能到達web服務網關接口django
django默認的七個中間件後端
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', ]
2、django中間件做用(********)瀏覽器
1.網站全局的身份校驗,訪問頻率限制,權限校驗。。。只要是涉及到全局的校驗你均可以在中間件完成服務器
2.django的中間件是全部web框架中作的最好的cookie
3、中間件執行順序session
-process_request()方法,從上往下執行 1.若是返回 HttpResponse對象,那麼會直接返回,再也不往下執行而是跳到同級別的process_response方法,直接往回走 2.請求來的時候,會通過每一箇中間件裏面的process_request方法(從上往下) -process_response,從下往上執行 1.必需要將response形參返回,這個形參指代的就是要返回給前端的數據 2.響應走的時候,會依次通過每個中間件裏面的process_response方法(從下往上)
4、自定義中間件app
1.導包
from django.utils.deprecation import MiddlewareMixin
2.定義類,繼承MiddlewareMixin
在app01應用中建立一個文件夾mymiddleware,再建立一個mdd.py文件
class MyMdd(MiddlewareMixin): def process_request(self,request): print('我是第一個中間件裏面的process_request方法') def process_response(self,request,response): print('我是第一個中間件裏面的process_response方法') return responseclass MyMdd1(MiddlewareMixin): def process_request(self,request): print('我是第二個中間件裏面的process_request方法') def process_response(self,request,response): print('我是第二個中間件裏面的process_response方法') return response
3.定義視圖函數
def index(request): print("view函數...") return HttpResponse("OK")
4.在settings中MIDDLEWARE註冊自定義中間件
MIDDLEWARE =[ 'mymiddleware.mdd.MyMdd', 'mymiddleware.mdd.MyMdd1', 'mymiddleware.mdd.MyMdd2', ]
5.設置路由
urlpatterns = [ url(r'^index/',view.index) ]
結果
我是第一個中間件裏面的process_request方法
我是第二個中間件裏面的process_request方法
view函數...
我是第二個中間件裏面的process_response方法
我是第一個中間件裏面的process_response方法
5、中間件五個能夠自定義的方法
須要掌握的方法:
1.process_request()方法 請求來的時候會走該方法
1.請求來的時候 會通過每一箇中間件裏面的process_request方法(從上往下) 2.若是方法裏面直接返回了HttpResponse對象 那麼會直接返回 再也不往下執行 基於該特色就能夠作訪問頻率限制,身份校驗,權限校驗
2.process_response()方法 響應回去的時候會走該方法
1.必須將response形參返回 由於這個形參指代的就是要返回給前端的數據 2.響應走的時候 會依次通過每個中間件裏面的process_response方法(從下往上)
須要瞭解的方法:
3.process_view()
在路由匹配成功執行視圖函數以前 觸發
4.process_exception()
當你的視圖函數報錯時,就會自動執行
5.process_template_response()
當你返回的HttpResponse對象中必須包含render屬性纔會觸發 def index(request): print('我是index視圖函數') def render(): return HttpResponse('什麼鬼玩意') obj = HttpResponse('index') obj.render = render return obj
總結:
你在書寫中間件的時候,只要形參中有response,你就應該順手將其返回,這個response就是要給前端的信息。 這五種方法有哪些特色: 1.都須要繼承MiddlewareMixin 2.在註冊中間件的時候,在settings中寫的路徑不能錯
CSRF——跨站請求僞造
1.什麼是CSRF攻擊
攻擊者盜用了你的身份,以你的名義發送惡意請求,對服務器來講這個請求是徹底合法的。
好比釣魚網站
2.CSRF攻擊原理
要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:
1.登陸受信任網站A,並在本地生成Cookie。
2.在不登出A的狀況下,訪問危險網站B。
釣魚網站例子
經過製做一個跟正兒八經的網站如出一轍的頁面,騙取用戶輸入信息 轉帳交易從而作手腳
轉帳交易的請求確確實實是發給了中國銀行,帳戶的錢也是確確實實少了
惟一不同的地方在於收款人帳戶不對
內部原理
在讓用戶輸入對方帳戶的那個input上面作手腳
給這個input不設置name屬性,在內部隱藏一個實現寫好的name和value屬性的input框
這個value的值 就是釣魚網站受益人帳號
如何去寫這個特殊的字符串呢?模版語法有一個固定的寫法{% csrf_token %},必須寫在form表單內
3.CSRF攻擊防範
防止釣魚網站的思路
網站會給用戶訪問的form表單頁面 偷偷塞一個隨機字符串
請求到來的時候 會先比對隨機字符串是否一致 若是不一致 直接拒絕(403)
該隨機字符串有如下特色
1.同一個瀏覽器每一次訪問都不同
2.不一樣瀏覽器絕對不會重複
4.CSRF在Django中的應用
1.在form表單中使用
<form action="" method="post"> {% csrf_token %} <p>username:<input type="text" name="username"></p> <p>password:<input type="text" name="password"></p> <input type="submit"> </form>
2.在ajax中使用,如何避免csrf校驗
方法一:先在form表單頁面上寫{% csrf_token%},利用標籤查找,獲取到該input鍵值消息
data{'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}
方法二:直接書寫'{{csrf_token}}'
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
新建一個js文件,存放如下代碼
function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });
5.CSRF禁用
1.CSRF全局禁用
註釋掉settings中MIDDLEWARE的中間件 'django.middleware.csrf.CsrfViewMiddleware',
2.CSRF局部禁用
from django.views.decorators.csrf import csrf_exempt,csrf_protect
#(前提是全局使用,沒有註釋csrf) 讓這個不用校驗,能夠局部使用
#當你網站全局須要校驗csrf的時候,有幾個不須要校驗該如何處理 @csrf_exempt def login(request): return HttpResponse('login') #(前提是全局禁用,註釋csrf,不會進行校驗) 設置就會進行校驗,局部禁用
#當你網站全局不校驗csrf的時候,有幾個須要校驗又該如何處理 @csrf_protect def lll(request): return HttpResponse('lll')
from django.views import View from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator # 這兩個裝飾器在給CBV裝飾的時候 有必定的區別 若是是csrf_protect 那麼有三種方式 # 第一種方式 # @method_decorator(csrf_protect,name='post') # 有效的 class MyView(View): # 第三種方式 # @method_decorator(csrf_protect) def dispatch(self, request, *args, **kwargs): res = super().dispatch(request, *args, **kwargs) return res def get(self,request): return HttpResponse('get') # 第二種方式 # @method_decorator(csrf_protect) # 有效的 def post(self,request): return HttpResponse('post')
若是是csrf_exempt 只有兩種(只能給dispatch裝) 特例 @method_decorator(csrf_exempt,name='dispatch') # 第二種能夠不校驗的方式 class MyView(View): # @method_decorator(csrf_exempt) # 第一種能夠不校驗的方式 def dispatch(self, request, *args, **kwargs): res = super().dispatch(request, *args, **kwargs) return res def get(self,request): return HttpResponse('get') def post(self,request): return HttpResponse('post')