2017-08-05 16 views
2

窗10,笨3,jquery的3jquery的AJAX調用由笨3禁止CSRF

我正在測試的AJAX功能,我通過使用$ .POST功能和發送到控制器的方法將數據裝載到一個div讀取文件併發回內容(我知道還有其他方法可以做,但這是一個測試)。阿賈克斯調用看起來像這樣

var btn = 'a[href="click-help"]' 
    $(btn).click(function(){ 

      $.post(
       base_url+'site/cal_help', 
       function(data){ 
        $('.cal-help').html(data); 
       }); 
     } 
     return false; 
    }); 

你可以看到,點擊按鈕不是一個窗體,而是一個鏈接。當csrf設置爲false時,這可以正常工作,但如果啓用了csrf,控制檯會將呼叫顯示爲禁止。經過在線研究,我試着通過的數據如下:

{ 
        '<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>' 
    }, 

但它沒有幫助。我怎樣才能解決它,而無需將csrf設置爲false,如果我希望將其用於網站中的其他元素,我寧願不這樣做?

回答

0

我確實遇到過在所有ajax請求中啓用CSRF保護項目的類似問題。然後我發現它發生是因爲csrf標記在每個請求上重新生成,這會導致禁止的錯誤,因爲標記不匹配。因此,解決方案將關閉每個請求上的CSRF令牌生成。你可以通過在你的config.php文件中設置這個選項來完成。

$config['csrf_regenerate'] = FALSE; 

請注意,當我檢查laravel的CSRF令牌時,它在所有請求中都不會發生變化。因此,將csrf再生選項更改爲false不會導致任何重大安全問題。如果上述方法不適用於您,請在下面評論。

1

我還在走這個,我發現一些更有趣的事情:

雖然你可以使用笨安全類是這樣的:

<?php echo $this->security->get_csrf_token_name(); ?> 
<?php echo $this->security->get_csrf_hash(); ?> 

在視圖和這些功能工作時,你也應該能夠在一個單獨的script.js文件噸至使用它們在腳本文件如

var hash = '<?php echo $this->security->get_csrf_hash();?>'; 
console.log(hash); 

這似乎在視圖腳本標籤內的工作,但如果他的控制檯只顯示打印出來的代碼。爲什麼會這樣呢?

但是我挖成JS字符串的方法,發現下面的工作來檢索哈希:

//get all cookies 
var x = document.cookie; 
//search for the csrf cookie name 
var posname = x.search('csrf_cookie_name'); 
//slice out hash itself which is always 32 characters long and these numbers work 
var hash = x.slice(posname+17,posname+49); 
console.log(hash); 

已經建立了一個變量等於哈希,您可以將以下數據添加到您的Ajax調用:

{ 
    'csrf_test_name' : hash 
}, 

我把所有這些放在'click'函數中,以便它找到最新版本的cookie。所以,我最終是這樣的:

var btn = '.btn-cal-help a'; 
$(btn).click(function(){ 
    var x = document.cookie; 
    var posname = x.search('csrf_cookie_name'); 
    var hash = x.slice(posname+17,posname+49); 
    //console.log(hash);  
     $.post(
      base_url + 'site/cal_help', 
      { 
       'csrf_test_name' : hash 
      }, 
      function(data){ 
       $('.cal-help').html(data); 
      }); 
    } 
    return false; 
}); 

而現在對我的作品(我的本地服務器上 - WAMP),即使我有「csrf_regenerate」設置爲TRUE爲好。

+0

我的回答將幫助你瞭解它是如何工作的,根據你的需要調整它 –

0

就這樣。讓你的令牌和哈希爲每個新的請求,並將其連接到您的文章數據

廣場這樣的事情在你的模型/控制器

$reponse = array(
       'csrfName' => $this->security->get_csrf_token_name(), 
       'csrfHash' => $this->security->get_csrf_hash() 
      ); 
// Your logic 

return $this->output 
          ->set_content_type('application/json') 
          ->set_status_header(200) 
          ->set_output(json_encode(array("regen" => $reponse, "response" => array("status" => $status, "message" => $message)))); 

在JavaScript部分

var csrfName = '<?php echo $this->security->get_csrf_token_name(); ?>', 
       csrfHash = '<?php echo $this->security->get_csrf_hash(); ?>'; 

$.ajax({ 
       url: __URL__, 
       type: "POST", 
       data: $form.serialize() + "&" + csrfName + "=" + csrfHash, 
       mimeType: "multipart/form-data", 
       contentType: false, 
       dataType: 'json', 
       cache: false, 
       processData: false, 

       success: function (data) { 

        csrfName = data.regen.csrfName; 
        csrfHash = data.regen.csrfHash; 

        if (data.response.status) // if STATUS = TRUE 
        { 
         if (data.response.message === "__WHATEVER__") { 
          // and message === "__WHATEVER__" 

         } 
        } 
       } 
      }); 
+0

對不起,我不關注這個。你已經使用Security類的函數來獲取控制器中的csrf名稱和哈希值,然後在javascript中完全獨立地找到它們。爲什麼呢?如果模糊,抱歉。另外,在我單獨的'script.js'文件中,使用Security類功能的JavaScript代碼不適用於我。如果我將所有js放在視圖中的腳本標記之間,它確實有效。你能解釋一下嗎? – Perkin5

+0

那麼,我把它放在模型中,是的,這個不會在外部js文件中工作。您需要使用cookie方法。 Js代碼獲取請求的令牌/散列,並且響應爲下一個請求分配新的請求,但如上所述,除非你的視圖中沒有js代碼,否則它不適用於你/一個選項可能是禁用csrf頁面在你的config.php - $ config ['csrf_exclude_uris'] –