vue-resource pos提交t數據時碰到Django csrf
最近在用Vue寫前端代碼,再用vue-resource向後台提交數據。項目後台是用python+Django開發的。下面我就復盤一下我出現問題的經過。
首先,想用vue進行數據交互只能引入vue-resource。
<script src="js/vue.js"></script>
<script src="js/vue-resource.js" ></script>
之後我使用vm.$http方法向後台發送數據,其實和jquery的AJAX方法差不多,需要定義發送的地址、請求類型和發送數據等。
this.$http({
url:"/data/",
data:JSON.stringify(Strdata),
method:"POST"
}).then(function(res){
alert(res.data);
});
由於POST請求需要修改發送date的Content-Type為application/json,所以要設置emulateJSON為true,就變成這樣了
this.$http({
url:"/data/",
data:JSON.stringify(Strdata),
method:"POST",
emulateJSON:true
}).then(function(res){
alert(res.data);
});
正常來說這樣就OK了,就可以拿到後台數據了。之後打開控制台,查看network,找到發出的data,看到HTTP狀態碼為302。
怎麼會被重定向到了登錄頁面,難道是登錄超時??
然後我看了看後台服務.....
不應該是登錄的問題啊,後面有請求成功返回啊,於是我對比了一下成功的請求和失敗請求的HTTP請求頭,發現好像是少了一個叫X-CSRFToken的東西。這是什麼東西呢,於是我就google了一下,得到如下答案:
Django 提供的 CSRF 防護機制django 第一次響應來自某個客戶端的請求時,會在伺服器端隨機生成一個 token,把這個 token 放在 cookie 里。然後每次 POST 請求都會帶上這個 token,
這樣就能避免被 CSRF 攻擊。
- 在返回的 HTTP 響應的 cookie 里,django 會為你添加一個 csrftoken 欄位,其值為一個自動生成的 token
- 在所有的 POST 表單時,必須包含一個 csrfmiddlewaretoken 欄位 (只需要在模板里加一個 tag, django 就會自動幫你生成,見下面)
- 在處理 POST 請求之前,django 會驗證這個請求的 cookie 里的 csrftoken 欄位的值和提交的表單里的 csrfmiddlewaretoken 欄位的值是否一樣。如果一樣,則表明這是一個合法的請求,否則,這個請求可能是來自於別人的 csrf 攻擊,返回 403 Forbidden.
- 在所有 ajax POST 請求里,添加一個 X-CSRFTOKEN header,其值為 cookie 里的 csrftoken 的值。
也就是說我每次向後台發送POST請求的時候,Django為了防止跨站請求偽造,即csrf攻擊,提供了CsrfViewMiddleware中間件來防禦csrf攻擊。這時我就知道為什麼之前將請求方式改為GET後成功了。
之後就想辦法在HTTP請求頭中設置X-CSRFToken了,我查了很多資料,看到最多的一種方法是這樣:
<meta id="token" name="token" value="{ csrf_token }">
Vue.http.headers.common["X-CSRFToken"] = document.querySelector("#token").getAttribute("value");
但是我試過還是重定向到登錄頁,不知道為什麼。之後想了想,實際就是獲取cookie裡面的csrftoken值,然後在賦值給HTTP請求頭裡面的X-CSRFToken就行了。
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]);
if (cookie.substring(0, name.length + 1) == (name + "=")) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
Vue.http.headers.common["X-CSRFToken"] = getCookie("csrftoken");
之後HTTP請求頭上的X-CSRFToken就有值了,響應也就成功了。
※Go語言學習筆記(六)net
※MySQL日期、時間相關內容
※goroutine 加 channel 代替遞歸調用,突破遞歸調用的層級限制
※WPF——TextBlock的ToolTip附加屬性
※設計模式解密(17)- 備忘錄模式
TAG:達人科技 |
※當「人見人愛」的泰迪熊碰到Ralph Lauren,看「時尚愛豆」 Polo bear 的崛起與回歸
※Apr.16 不想講話卻碰到個話癆 怎樣一秒躲開 Small Talk
※《英雄聯盟》NGA專訪Karsa:mlxg是我之前碰到過的最強力的對手
※在YG公司,碰到正在外出的bigbang成員
※當「Supreme極端粉絲」碰到「巴黎世家『辱華』保安」
※iPhone6升級IOS11.3系統,碰到這些問題,再也沒有煩惱了!
※BURBERRY新logo以不同形式現身於全球各地, 你碰到了嗎?
※NBA球星碰到假貨,韋德穿假supreme被認出,小托馬斯承認穿假AJ
※Hayley教口語,「碰到……」用英語怎麼說?
※Burberry經典款從不打折?那是沒碰到過它的瘋狂甩貨季!
※LOL小狗韓服Rank碰到小花生,被恐怖征服15分鐘!
※BLACKPINK LISA碰到泰文也沒聽出?網友:LISA啊,你是泰國人啊!
※FPS遊戲中最常見的5個bug,看看你碰到過幾個?
※金咕咕直播碰到微笑毛神:我C,結婚buff!微笑一字回復亮了
※李爾新:如果碰到跟我有beef的人,就用音樂說話
※泫雅碰到對手!這個171的長腿短髮girl,是當年《告白》里的班花
※當173cm的蘇有朋碰到176cm的王俊凱,網友:絕對有人謊報了身高!
※十二星座女感情中的對手,碰到這些心機girl,基本無解了!
※dnf盧克c換幽魂套打團,就是怕碰到這種事情!
※碰到ICE怎麼辦?