跨站請求僞造(csrf)中間件整理

一. CSRF中間件  
html

  字面意思跨站請求僞造; 即模仿個請求朝服務器發送,django中對跨站僞造的請求有相應的校驗ajax

     from django.views.decorators.csrf import csrf_exempt, csrf_protectdjango

    csrf_exempt  給單個視圖排除校驗,以裝飾器形式給某個視圖加上,則該視圖就不會進行校驗瀏覽器

                局部禁用的前提是全局有校驗服務器

    csrf_protect  給單個視圖必須校驗,以裝飾器形式給某個視圖加上,則該視圖就必須進行校驗cookie

                即便註釋調settings中的46行也必須得校驗.  局部使用的前提是全局沒有校驗函數

二. csrt源碼解析其校驗的本質大概流程是:post

  1. process_request,從請求的cookie中獲取csrftoken的值,保存爲scrf_tokenui

  2. process_view:this

     > 若是視圖函數加上了csrf_exempt的裝飾器  不作校驗

     > 若是請求方式是'GET', 'HEAD', 'OPTIONS', 'TRACE' 也不作校驗

     > 其它的請求方式就要進行校驗了,校驗的實質以下:

       1.request.POST中獲取csrfmiddlewaretoken對象的值

       2.從請求頭中獲取csrfmiddlewaretoken對象的值

       3.用獲取到的csrfmiddlewaretoken的值和csrftoken的值作比較,若是校驗成功,流程繼續;校驗不成功

          則拒絕;  12中只要有1個能獲取到csrfmiddlewaretoken的值便可,不用兩個中都有.

總結: 兩點要求,1.瀏覽器必須帶有cookie;  2. post請求體中或請求頭中要能獲取到csrfmiddlewaretoken

 

三.針對以上總結的兩點,作相應的處理,處理辦法以下

     確保瀏覽器帶有cookie的兩種方式:

          > form表單內加入{% csrf_token %}

          > 不使用{% csrf_token %},導入from django.views.decorators.csrf import ensure_csrf_cookie

             ensure_csrf_cookie以裝飾器形式加在視圖上,保證返回的相應有cookie

      確保能從post請求體中或請求頭信息中獲取到csrfmiddlewaretokende的方式:

        > 頁面中加入{% csrf_token %}標籤

         1.獲取標籤值,加入post請求體中,  csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()

         2.獲取標籤值,加入post請求頭中,  headers: {"X-CSRFToken": $('[name="csrfmiddlewaretoken"]').val()}

        > 上面12都是給單個的ajax請求加csrfmiddlewaretokende,這裏再介紹個經過引入js文件形式

          給全局全部ajax頭部加入csrfmiddlewaretokende的辦法,代碼思路以下: (萬能辦法)

         1.經過django官網提供的代碼來實現,首先項目下static文件夾內新建js文件,複製如下代碼:

         2.script標籤在html頁面導入新建的這個a.js文件, <script src=’/static/a.js’></script>

           它的做用是給每一個請求頭信息上加crsfmiddlewaretoken信息

     猜想: 引入js文件形式可同時讓瀏覽器帶cookie和讓請求頭帶crsfmiddlewaretoken信息,由於使用

           CBVajax文件上傳時,html中沒加{%csrf_token%},views中也沒用ensure_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);

    }

  }

});

相關文章
相關標籤/搜索