Django學習---CSRF

CSRF

 xss攻擊:假設咱們網站的評論裏面容許用戶寫js的時候,每一個人就會看到頁面會執行這個js代碼,有的是alert,不停的跳出彈框。這個還不算嚴重的,關鍵是若是js代碼運行的結果不顯示在頁面上,偷偷的 把cookie發到他本身那去,這樣攻擊者就可使用這個cookie登陸網站。ajax

CSRF:django

1.原理:cookie

發送請求,第一次打開頁面是get請求,請求數據,咱們不只把數據發送過去,並且還偷偷的發了一大堆字符串,這個字符串是加密的,只有本身能夠反解。xss

下一次咱們提交數據的時候,要帶着字符串來,這樣才容許提交,否則的話,就報錯,不容許提交數據。函數

這個通常體如今哪呢?post

咱們用django,若是咱們日後臺發送post的請求,咱們沒有把settings那個中間件註釋的話,頁面就直接出現403錯誤,好比:網站

我如今把那個代碼的註釋去掉:ui

咱們打開咱們的login頁面,無論寫什麼點擊提交,都會出現403錯誤:this

 

這個就是作了一層防禦,get提交方式沒有什麼問題,一旦你以post方式提交,後臺會先來去你發過來的請求裏面去找一下那個隨機字符串,這個是CSRF生成的字符串。加密

那咱們應該怎麼解決這個問題呢?人家這裏須要一個隨機字符串,咱們傳一個就能夠了。

在django的內部,也支持生成這個隨機的字符串:

在form中我加上這個一個變量:csrf_token:

咱們在刷新一下:

就多了一個字符串,這個字符串就是CSRF的token,之後再提交數據的時候就應該帶這個字符串。

可是咱們這樣在這裏放一個字符串是沒有用的,因此咱們要用到下面的東西:

咱們在頁面上沒有看到那個字符串了,可是咱們看一下生成的HTML代碼:

咱們生成了一個隱藏的input,咱們在提交數據的時候,後臺就可以拿到這個數據了,拿到了就能夠經過了。

那若是咱們沒有這個CSRFtoken,會出現什麼效果呢?

假設咱們先登陸咱們本身的網站,登陸成功以後 ,咱們先放着,咱們打開其餘的網站,提交表單登陸,提交到咱們的網站的網址上,若是咱們沒有這個token的話就直接提交了,可是若是有的話,其餘網站的表單不可能有咱們本身生成的token,就沒有辦法進行登陸,這樣就至關於作了一步防禦的工做。

上面是form表單提交數據,咱們使用的是csrf_token,那若是是ajax提交咱們應該怎麼作呢?

咱們上面看到了在HTML中生成了一個隱藏的input,裏面有一個字符串,其實在咱們的cookie中也生成了一個:

咱們若是ajax請求,咱們只須要拿到這個cookie的值,放到請求頭裏發過去就好了:

$(function(){

            $('#btn').click(function(){
                $.ajax({
                    url : '/login/',
                    type : 'POST', 
                    data : {'user':'root','passwd':'123'},
                    headers : {'X-CSRFtoken' : $.cookie('csrftoken')},
                    success : function (data) {

           },
       });
     });
});

 

這樣就能夠提交成功!

固然若是咱們下面有不少ajax操做,咱們能夠在ajaxSetup中添加以後,下面的ajax就不須要了:

<!--在這個裏面能夠對全部的ajax作一個配置-->
            $.ajaxSetup({
                beforeSend : function (xhr,settings) {<!--xhr:XMLHttpRequest 的對象,全部的ajax底層操做都是用這個,-->
                    xhr.setRequestHeader('X-CSRFtoken' , $.cookie('csrftoken'));
         }
})

 

 在django中咱們還支持:

咱們在MIDDLEWARE中把CSRF註釋了,每一個form提交的時候都要加上一個token,不加就沒法進行驗證,做用於所有。這個很明顯是不合理的,由於有的時候咱們說那個函數就不須要加CSRFtoken,會有這種需求。

咱們如今有一個需求,100form提交中有2個須要用到CSRFtoken驗證,那怎麼作呢?

局部:

  • @csrf_protect,爲當前函數強制設置防跨站請求僞造功能,即使settings中沒有設置全局中間件。
  • @csrf_exempt,取消當前函數防跨站請求僞造功能,即使settings中設置了全局中間件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

CSRF只有在post提交的時候才起做用,若是用get請求,那不須要csrftoken,那咱們能夠在上面的ajaxsetup中作判斷 

 

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);
                }
            }
        });
相關文章
相關標籤/搜索