pos提交提交數據時碰到Django csrf

  個人github(PS:但願star):https://github.com/thWinterSun/v-admin前端

  最近在用Vue寫前端代碼,再用vue-resource向後臺提交數據。項目後臺是用python+Django開發的。下面我就覆盤一下我出現問題的通過。vue

  首先,想用vue進行數據交互只能引入vue-resource。python

<script src="js/vue.js"></script>
<script src="js/vue-resource.js" ></script>

  以後我使用vm.$http方法向後臺發送數據,其實和jquery的AJAX方法差很少,須要定義發送的地址、請求類型和發送數據等。jquery

this.$http({
    url:'/data/',
    data:JSON.stringify(Strdata),
    method:'POST'
}).then(function(res){
    alert(res.data);                    
});

因爲POST請求須要修改發送date的Content-Type爲application/json,因此要設置emulateJSON爲true,就變成這樣了git

this.$http({
    url:'/data/',
    data:JSON.stringify(Strdata),
    method:'POST',
    emulateJSON:true
}).then(function(res){
    alert(res.data);                    
});

正常來講這樣就OK了,就能夠拿到後臺數據了。以後打開控制檯,查看network,找到發出的data,看到HTTP狀態碼爲302。github

怎麼會被重定向到了登陸頁面,難道是登陸超時??ajax

 

而後我看了看後臺服務.....django

不該該是登陸的問題啊,後面有請求成功返回啊,因而我對比了一下成功的請求和失敗請求的HTTP請求頭,發現好像是少了一個叫X-CSRFToken的東西。這是什麼東西呢,因而我就google了一下,獲得以下答案:json

Django 提供的 CSRF 防禦機制

django 第一次響應來自某個客戶端的請求時,會在服務器端隨機生成一個 token,把這個 token 放在 cookie 裏。而後每次 POST 請求都會帶上這個 token,服務器

這樣就能避免被 CSRF 攻擊。

  1. 在返回的 HTTP 響應的 cookie 裏,django 會爲你添加一個 csrftoken 字段,其值爲一個自動生成的 token
  2. 在全部的 POST 表單時,必須包含一個 csrfmiddlewaretoken 字段 (只須要在模板里加一個 tag, django 就會自動幫你生成,見下面)
  3. 在處理 POST 請求以前,django 會驗證這個請求的 cookie 裏的 csrftoken 字段的值和提交的表單裏的 csrfmiddlewaretoken 字段的值是否同樣。若是同樣,則代表這是一個合法的請求,不然,這個請求多是來自於別人的 csrf 攻擊,返回 403 Forbidden.
  4. 在全部 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就有值了,響應也就成功了。

 

相關文章
相關標籤/搜索