2011-09-01 166 views
10

這裏我的問題,Rails 3.1 - 忽略CSRF?

我有一個導軌3.1的應用程序,我試圖讓一個Ajax請求,但我得到的警告信息「警告:無法驗證CSRF令牌真實性」 ...

裏面我的佈局,我已經得到了helper方法「csrf_method_tag」,我添加下面的JavaScript代碼(不,如果它真的需要或不知道):

$.ajaxSetup({ 
    beforeSend: function(xhr) { 
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); 
    } 
}); 

我Gemfile中包含的寶石jquery-rails(> = 1.0.12),我需要jquery & jquery-ujs在我的application.js的頂部。

即使如此,仍會出現消息。我忘了什麼嗎?

感謝您的幫助。

+0

有相同的問題 - 登錄後,如果我更改頁面(使用設計和rpx可連接的寶石),我會註銷。讓我們知道您是否解決了這個問題 – Plattsy

+0

在加載發出請求的頁面的請求上發送的AJAX請求的頭文件中是否發送了相同的Cookie? CSRF令牌在symphony中通過當前會話進行驗證,該會話保存在另一個頭文件中(應該自動發送,但可能不在您的案例中)。 –

+0

看看我的答案在這裏:http://stackoverflow.com/questions/15239818/iframe-causes-cant-verify-csrf-token-authenticity-n-rails/15869772#15869772 – tinker

回答

7

對我來說什麼工作 - 在沒有窗體的情況下工作時 - 是將<%= form_authenticity_token %>的結果包含在ajax數據有效載荷中。於是,我像做了什麼了HTML建議通過tehprofessor:

<input id="tokentag" type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" /> 

然後在JavaScript:

tokentag = $('#tokentag').val() 
submitdata = { "authenticity_token": tokentag, ...+whatever else you need to include+...} 

那麼$.ajaxsubmitdata調用。

7

你可能甚至不需要你的代碼。缺省情況下,jquery-rails gem自動在所有Ajax請求上設置CSRF標記。

+0

我知道,但即使刪除JavaScript代碼,CSRF令牌似乎仍然被忽略... –

+0

您是使用標準的rails form_for和form_tag助手,還是使用自己的HTML標籤? –

+0

我使用任何形式...我使用請求來更新部分或獲得一些JSON。 –

0

您是否嘗試過使用具有真實性標記的隱藏表單元素?

<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token>" /> 

我有同樣的錯誤,並解決了它。這是因爲我沒有使用內置的幫助器...

+0

沒有,仍然沒有工作......我必須在本週結束前解決這個問題,我讓你知道,如果我找到了什麼... –

9

我有這個完全相同的麻煩。我試圖抓住一個JavaScript事件(you_tube播放器完成)和Ajax回到我的服務器讓我知道。我得到:

WARNING: Can't verify CSRF token authenticity

每當jQuery的ajax調用命中我的服務器。我在

$.ajaxSetup({ 
    beforeSend: function(xhr) { 
     xhr.setRequestHeader('X-CSRF-Token', 
          $('meta[name="csrf-token"]').attr('content')); 
    } 
}); 

上面加了你的代碼修正,它工作正常。我認爲,唯一的區別是在我的佈局,我有

<%= csrf_meta_tags %> 

,而不是作爲csrf_method_tag你在原來的文章中提到。
所以,謝謝你的修復,它在原來的文章。

+2

**請_don't_在你的帖子中使用簽名或標語**閱讀[ FAQ條目](http://stackoverflow.com/faq#signatures)瞭解更多信息。謝謝! –

0

其中一個原因可能是您在加載文檔之前進行AJAX調用,所以JQuery無法獲得CSRF令牌。

1

只需直接在您的AJAX調用上執行,它就能正常工作!

$.ajax({ 
      type: //method, 
      beforeSend: function(xhr){ 
       xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')) 
      }, 
      url: //parameter, 
      dataType: 'html', 
      success: function(data, textStatus, jqXHR) { 
       // some code 
      } 
    }); 
0

的問題是,你需要,因爲一旦一個標記使用的它就會失效一個Ajax POST請求後獲取一個新的令牌。下面是代碼來做到這一點:

在每當發表回覆發送這些參數添加到響應的軌道:

def someMethod: 
    result[:csrfParam] = request_forgery_protection_token 
    result[:csrfToken] = form_authenticity_token 
    render :json => result 
end 

現在的JS側,在每一個POST方法,你可以成功函數調用這個函數:

var setCsrfToken = function(param, token) { 
    if(param == null || token == null) { 
     console.error("New CSRF param/token not present"); 
    } 
    $("input[name='" + param + "']").val(token); 
} 

這樣的:

setCsrfToken(result["csrfParam"], result["csrfToken"]); 

此功能將重置所有POST表單中的所有authenticity_token參數,以便下一個請求具有有效的標記。您需要確保每次POST調用都會發生這種情況,否則您將繼續面臨此問題。另外,CSRF不是用來防止點擊劫持,它是一個單獨的攻擊,其他網站可以讓用戶點擊一個鏈接,在用戶的會話中執行網站上的一個動作。