警告:无法validationCSRF令牌真实性轨道
我发送数据从视图到控制器与AJAX和我得到这个错误:
警告:无法validationCSRF令牌的真实性
我想我必须发送这个令牌的数据。
有谁知道我该怎么做?
编辑:我的解决scheme
我通过将以下代码放在AJAX文章中:
headers: { 'X-Transaction': 'POST Example', 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') },
你应该做这个:
-
确保你的布局中有
<%= csrf_meta_tag %>
-
添加
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); } });
- 确保你的布局中有
<%= csrf_meta_tag %>
- 添加一个beforeSend以在ajax请求中包含csrf标记来设置标题。 这仅适用于
post
请求。
阅读csrf-token的代码可以在rails/jquery-ujs
,所以使用它最简单,如下所示:
$.ajax({ url: url, method: 'post', beforeSend: $.rails.CSRFProtection, data: { // ... } })
我只是以为我会把这个链接在这里,因为这篇文章有你正在寻找的大部分答案,这也是非常有趣的
这里顶部投票的答案是正确的,但是如果你正在执行跨域请求是行不通的,因为会话将不可用,除非你明确告诉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不起作用,所以如果您看到这个错误,这是另一个可能的原因。