http://www.cnblogs.com/zhaof/p/6281482.html html
django爲用戶實現防止跨站請求僞造的功能,經過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成。而對於django中設置防跨站請求僞造功能有分爲全局和局部。前端
全局:ajax
中間件 django.middleware.csrf.CsrfViewMiddlewaredjango
局部:後端
@csrf_protect,爲當前函數強制設置防跨站請求僞造功能,即使settings中沒有設置全局中間件。cookie
@csrf_exempt,取消當前函數防跨站請求僞造功能,即使settings中設置了全局中間件。函數
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protectpost
當用post提交數據的時候,django會去檢查是否有一個csrf的隨機字符串,若是沒有就會報錯,這也是以前咱們一直將其註釋的緣由,錯誤以下:ui
在django內部支持生成這個隨機字符串this
在form表單裏面須要添加{%csrf_token%}
這樣當你查看頁面源碼的時候,能夠看到form中有一個input是隱藏的
總結原理:當用戶訪問login頁面的時候,會生成一個csrf的隨機字符串,,而且cookie中也存放了這個隨機字符串,當用戶再次提交數據的時候會帶着這個隨機字符串提交,若是沒有這個隨機字符串則沒法提交成功
cookie中存放的csrftoken以下圖
由於cookie中一樣存在csrftoken,因此能夠在js中經過:
$.cooke("cstftoken")獲取
若是經過ajax進行提交數據,這裏提交的csrftoken是經過請求頭中存放,須要提交一個字典類型的數據,即這個時候須要一個key。
在views中的login函數中:from django.conf import settings,而後打印print(settings.CSRF_HEADER_NAME)
這裏須要注意一個問題,這裏導入的settings並非咱們在項目文件下看到的settings.py文件,這裏是是一個全局的settings配置,而當咱們在項目目錄下的settings.py中配置的時候,咱們添加的配置則會覆蓋全局settings中的配置
print(settings.CSRF_HEADER_NAME)打印的內容爲:HTTP_X_CSRFTOKEN
這裏的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,因此實際傳遞的是就是X_CSRFtoken,而在前端頁面的ajax傳遞的時候因爲不能使用下劃線因此傳遞的是X_CSRFtoken
下面是在前端ajax中寫的具體內容:
$("#btn1").click(function () { $.ajax({ url:"/login/", type:"POST", data:{"usr":"root","pwd":"123"}, headers:{ "X-CSRFtoken":$.cookie("csrftoken")}, success:function (arg) { } }) })
可是若是頁面中有多個ajax請求的話就在每一個ajax中添加headers信息,因此能夠經過下面方式在全部的ajax中都添加
$.ajaxSetup({ beforeSend:function (xhr,settings) { xhr.setRequestHeader("X-CSRFtoken",$.cookie("csrftoken")) } });
這樣就會在提交ajax以前執行這個方法,從而在全部的ajax裏都加上這個csrftoken
這裏的xhr是XMLHttpRequest的簡寫,ajax調用的就是這個方法
若是想要實如今當get方式的時候不須要提交csrftoken,當post的時候須要,實現這種效果的代碼以下:
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); } } });
這樣就實現了當GET|HEAD|OPTIONS|TRACE這些方式請求的時候不須要提交csrftoken
一、 csrf在ajax提交的時候經過請求頭傳遞的給後臺的
二、 csrf在前端的key爲:X-CSRFtoken,到後端的時候django會自動添加HTTP_,而且最後爲HTTP_X_CSRFtoken
三、 csrf在form中提交的時須要在前端form中添加{%csrftoken%}