Django框架(十二)-- 中間件、CSRF跨站請求僞造

中間件前端

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的值 就是釣魚網站受益人帳號

如何區分釣魚網站和正經網站?在正經網站返回頁面的時候,在form表單中偷偷塞一個特殊的字符串,後端記下該頁面對應的字符串的值,等用戶發post請求來的時候,我先去校驗特殊的字符串是否匹配

如何去寫這個特殊的字符串呢?模版語法有一個固定的寫法{% 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校驗

  • 有兩種方法,經過修改ajax的data

  方法一:先在form表單頁面上寫{% csrf_token%},利用標籤查找,獲取到該input鍵值消息

data{'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}

  方法二:直接書寫'{{csrf_token}}'

data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
  • 還能夠將獲取隨機鍵值對的方法,寫到一個js文件中,而後導入這個文件便可

  新建一個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局部禁用

  • 在FBV中,直接加載FBV就好了 (在頁面不加csrf_token狀況下)
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')
  • 在CBV中,只能在dispatch方法或者類上面
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')
相關文章
相關標籤/搜索