Django進(jìn)階之CSRF的解決
簡(jiǎn)介
django為用戶實(shí)現(xiàn)防止跨站請(qǐng)求偽造的功能,通過(guò)中間件 django.middleware.csrf.CsrfViewMiddleware 來(lái)完成。而對(duì)于django中設(shè)置防跨站請(qǐng)求偽造功能有分為全局和局部。
全局:
中間件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,為當(dāng)前函數(shù)強(qiáng)制設(shè)置防跨站請(qǐng)求偽造功能,即便settings中沒(méi)有設(shè)置全局中間件。
@csrf_exempt,取消當(dāng)前函數(shù)防跨站請(qǐng)求偽造功能,即便settings中設(shè)置了全局中間件。
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect
原理
當(dāng)用post提交數(shù)據(jù)的時(shí)候,django會(huì)去檢查是否有一個(gè)csrf的隨機(jī)字符串,如果沒(méi)有就會(huì)報(bào)錯(cuò),這也是之前我們一直將其注釋的原因,錯(cuò)誤如下:
在django內(nèi)部支持生成這個(gè)隨機(jī)字符串
通過(guò)form提交
在form表單里面需要添加{%csrf_token%}
這樣當(dāng)你查看頁(yè)面源碼的時(shí)候,可以看到form中有一個(gè)input是隱藏的
總結(jié)原理:當(dāng)用戶訪問(wèn)login頁(yè)面的時(shí)候,會(huì)生成一個(gè)csrf的隨機(jī)字符串,,并且cookie中也存放了這個(gè)隨機(jī)字符串,當(dāng)用戶再次提交數(shù)據(jù)的時(shí)候會(huì)帶著這個(gè)隨機(jī)字符串提交,如果沒(méi)有這個(gè)隨機(jī)字符串則無(wú)法提交成功
cookie中存放的csrftoken如下圖
通過(guò)ajax提交
因?yàn)閏ookie中同樣存在csrftoken,所以可以在js中通過(guò):
$.cooke("cstftoken")獲取
如果通過(guò)ajax進(jìn)行提交數(shù)據(jù),這里提交的csrftoken是通過(guò)請(qǐng)求頭中存放,需要提交一個(gè)字典類型的數(shù)據(jù),即這個(gè)時(shí)候需要一個(gè)key。
在views中的login函數(shù)中:from django.conf import settings,然后打印print(settings.CSRF_HEADER_NAME)
這里需要注意一個(gè)問(wèn)題,這里導(dǎo)入的settings并不是我們?cè)陧?xiàng)目文件下看到的settings.py文件,這里是是一個(gè)全局的settings配置,而當(dāng)我們?cè)陧?xiàng)目目錄下的settings.py中配置的時(shí)候,我們添加的配置則會(huì)覆蓋全局settings中的配置
print(settings.CSRF_HEADER_NAME)打印的內(nèi)容為:HTTP_X_CSRFTOKEN
這里的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,所以實(shí)際傳遞的是就是X_CSRFtoken,而在前端頁(yè)面的ajax傳遞的時(shí)候由于不能使用下劃線所以傳遞的是X_CSRFtoken
下面是在前端ajax中寫(xiě)的具體內(nèi)容:
$("#btn1").click(function () { $.ajax({ url:"/login/", type:"POST", data:{"usr":"root","pwd":"123"}, headers:{ "X-CSRFtoken":$.cookie("csrftoken")}, success:function (arg) { } }) })
但是如果頁(yè)面中有多個(gè)ajax請(qǐng)求的話就在每個(gè)ajax中添加headers信息,所以可以通過(guò)下面方式在所有的ajax中都添加
$.ajaxSetup({ beforeSend:function (xhr,settings) { xhr.setRequestHeader("X-CSRFtoken",$.cookie("csrftoken")) } });
這樣就會(huì)在提交ajax之前執(zhí)行這個(gè)方法,從而在所有的ajax里都加上這個(gè)csrftoken
這里的xhr是XMLHttpRequest的簡(jiǎn)寫(xiě),ajax調(diào)用的就是這個(gè)方法
如果想要實(shí)現(xiàn)在當(dāng)get方式的時(shí)候不需要提交csrftoken,當(dāng)post的時(shí)候需要,實(shí)現(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); } } });
這樣就實(shí)現(xiàn)了當(dāng)GET|HEAD|OPTIONS|TRACE這些方式請(qǐng)求的時(shí)候不需要提交csrftoken
總結(jié)
1、 csrf在ajax提交的時(shí)候通過(guò)請(qǐng)求頭傳遞的給后臺(tái)的
2、 csrf在前端的key為:X-CSRFtoken,到后端的時(shí)候django會(huì)自動(dòng)添加HTTP_,并且最后為HTTP_X_CSRFtoken
3、 csrf在form中提交的時(shí)需要在前端form中添加{%csrftoken%}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Django中如何防范CSRF跨站點(diǎn)請(qǐng)求偽造攻擊的實(shí)現(xiàn)
- 詳解利用django中間件django.middleware.csrf.CsrfViewMiddleware防止csrf攻擊
- 詳解Django的CSRF認(rèn)證實(shí)現(xiàn)
- Django csrf 驗(yàn)證問(wèn)題的實(shí)現(xiàn)
- django框架CSRF防護(hù)原理與用法分析
- Django CSRF跨站請(qǐng)求偽造防護(hù)過(guò)程解析
- Django使用中間鍵實(shí)現(xiàn)csrf認(rèn)證詳解
- python Django里CSRF 對(duì)應(yīng)策略詳解
- Python Django框架防御CSRF攻擊的方法分析
相關(guān)文章
Python異常處理try語(yǔ)句應(yīng)用技巧實(shí)例探究
異常處理在Python中是至關(guān)重要的,try-except是用于捕獲和處理異常的核心機(jī)制之一,本文就帶大家深入了解如何使用try-except,處理各種異常情況2024-01-01python多進(jìn)程(加入進(jìn)程池)操作常見(jiàn)案例
這篇文章主要介紹了python多進(jìn)程(加入進(jìn)程池)操作,結(jié)合常見(jiàn)案例形式分析了Python多進(jìn)程復(fù)制文件、加入進(jìn)程池及多進(jìn)程聊天等相關(guān)操作技巧,需要的朋友可以參考下2019-10-10Python調(diào)用釘釘自定義機(jī)器人的實(shí)現(xiàn)
這篇文章主要介紹了Python調(diào)用釘釘自定義機(jī)器人的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01python使用opencv實(shí)現(xiàn)馬賽克效果示例
這篇文章主要介紹了python使用opencv實(shí)現(xiàn)馬賽克效果,結(jié)合實(shí)例形式分析了Python使用cv2模塊操作圖片實(shí)現(xiàn)馬賽克效果的相關(guān)技巧,需要的朋友可以參考下2019-09-09pandas 取出表中一列數(shù)據(jù)所有的值并轉(zhuǎn)換為array類型的方法
下面小編就為大家分享一篇pandas 取出表中一列數(shù)據(jù)所有的值并轉(zhuǎn)換為array類型的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04關(guān)于Pycharm配置翻譯插件Translation報(bào)錯(cuò)更新TTK失敗不能使用的問(wèn)題
這篇文章主要介紹了關(guān)于Pycharm配置翻譯插件Translation報(bào)錯(cuò)更新TTK失敗不能使用的問(wèn)題,本文通過(guò)圖文并茂的形式給大家分享解決方案,需要的朋友可以參考下2022-04-04python中通過(guò)預(yù)先編譯正則表達(dá)式提高效率
Python是一個(gè)很酷的語(yǔ)言,因?yàn)槟憧梢栽诤芏痰臅r(shí)間內(nèi)利用很少的代碼做很多事情,再加上正則表達(dá)式就更能體現(xiàn)其效果,下面這篇文章主要給大家介紹了關(guān)于python中通過(guò)預(yù)先編譯正則表達(dá)式提高效率的相關(guān)資料,需要的朋友可以參考下。2017-09-09redis之django-redis的簡(jiǎn)單緩存使用
本篇文章介紹了redis之django-redis的簡(jiǎn)單緩存使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06一篇文章帶你順利通過(guò)Python OpenCV入門(mén)階段
這篇文章主要介紹了Python OpenCV的知識(shí)體系,文章中涉及到的知識(shí)點(diǎn)很多,需要了解這方面知識(shí)的小伙伴可以慢慢理解,慢慢學(xué)習(xí)2021-08-08