您好,登錄后才能下訂單哦!
簡介
django為用戶實現(xiàn)防止跨站請求偽造的功能,通過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成。而對于django中設(shè)置防跨站請求偽造功能有分為全局和局部。
全局:
中間件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,為當前函數(shù)強制設(shè)置防跨站請求偽造功能,即便settings中沒有設(shè)置全局中間件。
@csrf_exempt,取消當前函數(shù)防跨站請求偽造功能,即便settings中設(shè)置了全局中間件。
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect
原理
當用post提交數(shù)據(jù)的時候,django會去檢查是否有一個csrf的隨機字符串,如果沒有就會報錯,這也是之前我們一直將其注釋的原因,錯誤如下:
在django內(nèi)部支持生成這個隨機字符串
通過form提交
在form表單里面需要添加{%csrf_token%}
這樣當你查看頁面源碼的時候,可以看到form中有一個input是隱藏的
總結(jié)原理:當用戶訪問login頁面的時候,會生成一個csrf的隨機字符串,,并且cookie中也存放了這個隨機字符串,當用戶再次提交數(shù)據(jù)的時候會帶著這個隨機字符串提交,如果沒有這個隨機字符串則無法提交成功
cookie中存放的csrftoken如下圖
通過ajax提交
因為cookie中同樣存在csrftoken,所以可以在js中通過:
$.cooke("cstftoken")獲取
如果通過ajax進行提交數(shù)據(jù),這里提交的csrftoken是通過請求頭中存放,需要提交一個字典類型的數(shù)據(jù),即這個時候需要一個key。
在views中的login函數(shù)中:from django.conf import settings,然后打印print(settings.CSRF_HEADER_NAME)
這里需要注意一個問題,這里導(dǎo)入的settings并不是我們在項目文件下看到的settings.py文件,這里是是一個全局的settings配置,而當我們在項目目錄下的settings.py中配置的時候,我們添加的配置則會覆蓋全局settings中的配置
print(settings.CSRF_HEADER_NAME)打印的內(nèi)容為:HTTP_X_CSRFTOKEN
這里的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,所以實際傳遞的是就是X_CSRFtoken,而在前端頁面的ajax傳遞的時候由于不能使用下劃線所以傳遞的是X_CSRFtoken
下面是在前端ajax中寫的具體內(nèi)容:
$("#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之前執(zhí)行這個方法,從而在所有的ajax里都加上這個csrftoken
這里的xhr是XMLHttpRequest的簡寫,ajax調(diào)用的就是這個方法
如果想要實現(xiàn)在當get方式的時候不需要提交csrftoken,當post的時候需要,實現(xiàn)這種效果的代碼如下:
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); } } });
這樣就實現(xiàn)了當GET|HEAD|OPTIONS|TRACE這些方式請求的時候不需要提交csrftoken
總結(jié)
1、 csrf在ajax提交的時候通過請求頭傳遞的給后臺的
2、 csrf在前端的key為:X-CSRFtoken,到后端的時候django會自動添加HTTP_,并且最后為HTTP_X_CSRFtoken
3、 csrf在form中提交的時需要在前端form中添加{%csrftoken%}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。