字面意思跨站請求僞造; 即模仿個請求朝服務器發送,django中對跨站僞造的請求有相應的校驗python
from django.views.decorators.csrf import csrf_exempt, csrf_protectajax
csrf_exempt 給單個視圖排除校驗,以裝飾器形式給某個視圖加上,則該視圖就不會進行校驗django
局部禁用的前提是全局有校驗瀏覽器
csrf_protect 給單個視圖必須校驗,以裝飾器形式給某個視圖加上,則該視圖就必須進行校驗服務器
即便註釋調settings中的46行也必須得校驗. 局部使用的前提是全局沒有校驗cookie
二. csrt源碼解析其校驗的本質大概流程是:函數
1. 在process_request內,從請求的cookie中獲取csrftoken的值,保存爲scrf_tokenpost
2. 在process_view內:ui
> 若是視圖函數加上了csrf_exempt的裝飾器 不作校驗
> 若是請求方式是'GET', 'HEAD', 'OPTIONS', 'TRACE' 也不作校驗
> 其它的請求方式就要進行校驗了,校驗的實質以下:
1.從request.POST中獲取csrfmiddlewaretoken對象的值
2.從請求頭中獲取csrfmiddlewaretoken對象的值
3.用獲取到的csrfmiddlewaretoken的值和csrftoken的值作比較,若是校驗成功,流程繼續;校驗不成功
則拒絕; 1和2中只要有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()}
> 上面1或2都是給單個的ajax請求加csrfmiddlewaretokende,這裏再介紹個經過引入js文件形式
給全局全部ajax頭部加入csrfmiddlewaretokende的辦法,代碼思路以下: (萬能辦法)
1.經過django官網提供的代碼來實現,首先項目下static文件夾內新建js文件,複製如下代碼:
2.以script標籤在html頁面導入新建的這個a.js文件, <script src=’/static/a.js’></script>
它的做用是給每一個請求頭信息上加crsfmiddlewaretoken信息
猜想: 引入js文件形式可同時讓瀏覽器帶cookie和讓請求頭帶crsfmiddlewaretoken信息,由於使用
CBV寫ajax文件上傳時,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); } } });