警告:无法validationCSRF令牌真实性轨道

我发送数据从视图到控制器与AJAX和我得到这个错误:

警告:无法validationCSRF令牌的真实性

我想我必须发送这个令牌的数据。

有谁知道我该怎么做?

编辑:我的解决scheme

我通过将以下代码放在AJAX文章中:

headers: { 'X-Transaction': 'POST Example', 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }, 

你应该做这个:

  1. 确保你的布局中有<%= csrf_meta_tag %>

  2. 添加beforeSend到所有的ajax请求来设置如下所示的头部:


 $.ajax({ url: 'YOUR URL HERE', type: 'POST', beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}, data: 'someData=' + someData, success: function(response) { $('#someDiv').html(response); } }); 

要发送所有请求中的令牌,您可以使用:

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

最好的方法是使用<%= form_authenticity_token.to_s %>直接在rails代码中打印出令牌。 你不需要使用JavaScript来searchdom的csrf标记,因为其他post提到。 只需添加如下的标题选项;

 $.ajax({ type: 'post', data: $(this).sortable('serialize'), headers: { 'X-CSRF-Token': '<%= form_authenticity_token.to_s %>' }, complete: function(request){}, url: "<%= sort_widget_images_path(@widget) %>" }) 

如果我没有记错的话,你必须将下面的代码添加到你的表单中,以摆脱这个问题:

 <%= token_tag(nil) %> 

不要忘记参数。

从旧的应用程序升级到rails 3.1,包括csrf元标记仍然没有解决它。 在rubyonrails.org博客上,他们提供了一些升级技​​巧,特别是jQuery的这一行,应该放在布局的头部:

 $(document).ajaxSend(function(e, xhr, options) { var token = $("meta[name='csrf-token']").attr("content"); xhr.setRequestHeader("X-CSRF-Token", token); }); 

从这个博客文章: http : //weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails 。

在我的情况下,会话正在重置每个Ajax请求。 添加上面的代码解决了这个问题。

确实是最简单的方法。 不要打扰改变标题。

确保你有:

 <%= csrf_meta_tag %> in your layouts/application.html.erb 

只要做一个隐藏的input字段,如下所示:

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

或者,如果你想要一个jQuery ajax后:

 $.ajax({ type: 'POST', url: "<%= someregistration_path %>", data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" }, error: function( xhr ){ alert("ERROR ON SUBMIT"); }, success: function( data ){ //data response can contain what we want here... console.log("SUCCESS, data="+data); } }); 
  1. 确保你的布局中有<%= csrf_meta_tag %>
  2. 添加一个beforeSend以在ajax请求中包含csrf标记来设置标题。 这仅适用于post请求。

阅读csrf-token的代码可以在rails/jquery-ujs ,所以使用它最简单,如下所示:

 $.ajax({ url: url, method: 'post', beforeSend: $.rails.CSRFProtection, data: { // ... } }) 

我只是以为我会把这个链接在这里,因为这篇文章有你正在寻找的大部分答案,这也是非常有趣的

http://www.kalzumeus.com/2011/11/17/i-saw-an-extremely-subtle-bug-today-and-i-just-have-to-tell-someone/

这里顶部投票的答案是正确的,但是如果你正在执行跨域请求是行不通的,因为会话将不可用,除非你明确告诉jQuery通过会话cookie。 以下是如何做到这一点:

 $.ajax({ url: url, type: 'POST', beforeSend: function(xhr) { xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')) }, xhrFields: { withCredentials: true } }); 

你可以像下面这样全局编写它。

正常JS:

 $(function(){ $('#loader').hide() $(document).ajaxStart(function() { $('#loader').show(); }) $(document).ajaxError(function() { alert("Something went wrong...") $('#loader').hide(); }) $(document).ajaxStop(function() { $('#loader').hide(); }); $.ajaxSetup({ beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))} }); }); 

咖啡脚本:

  $('#loader').hide() $(document).ajaxStart -> $('#loader').show() $(document).ajaxError -> alert("Something went wrong...") $('#loader').hide() $(document).ajaxStop -> $('#loader').hide() $.ajaxSetup { beforeSend: (xhr) -> xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')) } 

如果您使用的JavaScript与jQuery在您的窗体中生成令牌,这将工作:

 <input name="authenticity_token" type="hidden" value="<%= $('meta[name=csrf-token]').attr('content') %>" /> 

显然,你需要在Ruby布局中有<%= csrf_meta_tag %>

使用jquery.csrf( https://github.com/swordray/jquery.csrf )。

  • Rails 5.1或更高版本

     $ yarn add jquery.csrf 
     //= require jquery.csrf 
  • Rails 5.0或之前

     source 'https://rails-assets.org' do gem 'rails-assets-jquery.csrf' end 
     //= require jquery.csrf 
  • 源代码

     (function($) { $(document).ajaxSend(function(e, xhr, options) { var token = $('meta[name="csrf-token"]').attr('content'); if (token) xhr.setRequestHeader('X-CSRF-Token', token); }); })(jQuery); 

对于那些你需要一个非jQuery的答案,你可以简单地添加以下内容:

 xmlhttp.setRequestHeader('X-CSRF-Token',$('meta [name =“csrf-token”]')。attr('content'));

在这里可以看到一个非常简单的例子:

 xmlhttp.open( “POST”, “example.html的”,TRUE);
 xmlhttp.setRequestHeader('X-CSRF-Token',$('meta [name =“csrf-token”]')。attr('content'));
 xmlhttp.send();

NOP

我错过了我的application.js中的以下行

 //= require jquery_ujs 

我replace它和它的工作..

如果你没有使用jQuery,并使用API​​来获取请求,你可以使用下面的命令获取csrf-token

document.querySelector('meta[name="csrf-token"]').getAttribute('content')

 fetch('/users', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')}, credentials: 'same-origin', body: JSON.stringify( { id: 1, name: 'some user' } ) }) .then(function(data) { console.log('request succeeded with JSON response', data) }).catch(function(error) { console.log('request failed', error) }) 

如果有人需要与Uploadify和Rails 3.2相关的帮助(像我这样的博客),这个示例应用程序可能会有所帮助: https : //github.com/n0ne/Uploadify-Carrierwave-Rails-3.2.3/blob/master /app/views/pictures/index.html.erb

在这个应用程序中检查控制器解决scheme

我正在使用Rails 4.2.4,并不能解决为什么我得到:

 Can't verify CSRF token authenticity 

我在布局中:

 <%= csrf_meta_tags %> 

在控制器中:

 protect_from_forgery with: :exception 

调用tcpdump -A -s 999 -i lo port 3000正在显示正在设置的头(尽pipe不需要用ajaxSetup设置头 – 已经完成了):

 X-CSRF-Token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest DNT: 1 Content-Length: 125 authenticity_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

最后它失败了,因为我关掉了cookies。 如果没有启用cookie,CSRF不起作用,所以如果您看到这个错误,这是另一个可能的原因。