警告:无法验证CSRF令牌的真实性
我认为我必须将此令牌与数据一起发送。
有人知道我该怎么做吗?
编辑:我的解决方案
我这样做是通过将以下代码放入AJAX帖子中:
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
#1 楼
您应该执行以下操作:确保布局中包含
<%= 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')
}
});
评论
谢谢!像魅力一样为我工作!
– Misha Moroshko
2012年7月9日在13:18
Rails团队提供的jQuery UJS库自动将CSRF令牌添加到jQuery AJAX请求中。自述文件包含有关如何进行设置的说明。 github.com/rails/jquery-ujs/blob/master/src/rails.js#L91
–詹姆斯·康罗伊·芬恩
2012年9月2日上午10:53
请注意,您可以使用$ .ajaxSetup函数一次为所有请求设置标头。
–Pieter Jongsma
13年2月24日在12:50
优秀的!一直在寻找这个答案。无缝工作。谢谢!
–cassi.lup
2013年4月30日19:27
请注意,如果您按照上述建议使用jQuery UJS,则需要确保rails-ujs包含在jquery包含之后,否则将失败,并出现与op相同的错误。
– Topher Fangio
17年9月12日在16:43
#2 楼
最好的方法实际上是使用<%= form_authenticity_token.to_s %>
直接在您的rails代码中打印出令牌。您无需使用javascript即可在dom中搜索csrf令牌,如其他帖子所述。只需添加headers选项,如下所示:$.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) %>"
})
评论
您可以为$ .ajaxSetup()添加标头,而不是为每个ajax命令执行此操作。
–斯科特·麦克米兰(Scott McMillin)
11年11月29日在1:29
我宁愿建议使用此答案...
–opsidao
2012年7月23日在11:11
我不太喜欢在JavaScript中使用ERB的方法。
–radixhound
2012年7月27日在21:39
这迫使您使用ERB生成JavaScript,这是非常有限的。即使在某些地方ERB可能很适合,但在其他地方却没有,再加上它只是为了获得代币将是浪费。
–袜子僧侣
2014年4月3日23:36
#3 楼
如果我没记错的话,必须将以下代码添加到表单中,以解决此问题:<%= token_tag(nil) %>
不要忘记该参数。
评论
实际上,这应该是:<%= token_tag(nil)%>。然后,您将获得自动生成的令牌。
–szeryf
2012年5月16日19:54
#4 楼
确实是最简单的方法。不必更改标题。请确保您具有:
<%= csrf_meta_tag %> in your layouts/application.html.erb
只需执行如下所示的隐藏输入字段即可:
<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);
}
});
评论
将隐藏的输入字段添加到我的输入表单中为我解决了这个问题。
– Teemu Leisti
2014-09-28 21:36
如果您使用Rails的表单助手,这将自动完成。
– Jason FB
19年2月18日在16:04
#5 楼
从较旧的应用升级到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请求。添加以上代码即可解决该问题。
#6 楼
确保布局中包含
<%= csrf_meta_tag %>
添加
beforeSend
以在ajax请求中包含csrf令牌以设置标头。这仅对于post
请求是必需的。rails/jquery-ujs
中提供了读取csrf令牌的代码,因此,恕我直言,最简单的方法就是使用它,如下所示:$.ajax({
url: url,
method: 'post',
beforeSend: $.rails.CSRFProtection,
data: {
// ...
}
})
评论
无需重新实现Rails已经包含的内容即可轻松完成。这应该是选定的答案。
– jiehanzheng
17年2月1日,下午3:34
在Rails 5.1中也可以使用:标头:{'X-CSRF-Token':Rails.csrfToken()}
–奥尔
18-3-15在22:09
@nathanvda,也许您可以回答这个类似的问题:stackoverflow.com/questions/50159847/…
–user4412054
18年5月6日在22:47
#7 楼
我只是想我将其链接到这里,因为本文包含了您正在寻找的大多数答案,而且也很有趣http://www.kalzumeus.com/2011/11/17 /我今天看到一个极其微妙的错误,并且我已经告诉了某人/
#8 楼
此处票数最高的答案是正确的,但如果您执行跨域请求,则该答案将不起作用,因为除非您明确告诉jQuery传递会话cookie,否则该会话将不可用。操作方法如下:$.ajax({
url: url,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
xhrFields: {
withCredentials: true
}
});
评论
请问您能否回答这个非常相似的问题? stackoverflow.com/questions/50159847/…
–user4412054
18年5月6日在19:41
#9 楼
您可以像下面这样全局地编写它。普通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'))
}
#10 楼
哎呀..我错过了我的application.js中的以下行。js
//= require jquery_ujs
我替换了它并正常工作。.
=======更新=========
5年后,我又遇到了相同的错误,现在有了全新的Rails 5.1.6,我又找到了这个帖子就像生活圈一样。
现在的问题是:
默认情况下,Rails 5.1删除了对jquery和jquery_ujs的支持,并添加了
//= require rails-ujs in application.js
它执行以下操作:
执行各种动作的确认对话框;
从超链接发出非GET请求;
创建表格或超链接使用Ajax异步提交数据;
已自动在表单提交上禁用了提交按钮,以防止双击。
(来自:https://github.com/rails/rails-ujs/tree/master)
但是为什么不为ajax请求包括csrf令牌?如果有人对此有详细了解,请评论我。非常感谢。
无论如何,我在自定义js文件中添加了以下内容,以使其正常工作(感谢其他答复,以帮助我到达此代码):
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-Token': Rails.csrfToken()
}
});
----
----
});
评论
这也是我需要做的。出现这个问题的原因是因为我正在构建一个React App来慢慢替换现有的Rails App。由于现有应用程序中存在大量JavaScript杂音,因此我创建了访问其他JavaScript文件的不同布局,但未能包含jquery_ujs。那是诀窍。
–威廉·贾德(Wylliam Judd)
17-09-26在20:46
是的,有时如果我们在返工时错过了这一点,请重构某些东西。很难发现出了什么问题。因为我们没有手动做任何事情来使它起作用,所以Rails会自动包含它。我们认为它已经在那里。感谢您提供此类社交Qn / Ans网站
–阿比
18年4月19日在10:12
也许您可以回答这个类似的问题:stackoverflow.com/questions/50159847/…
–user4412054
18年5月6日在22:46
#11 楼
如果您不使用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)
})
评论
请问您能否回答这个非常相似的问题? stackoverflow.com/questions/50159847/…
–user4412054
18年5月6日在19:42
#12 楼
使用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);
/>
评论
在使用webpack的5.1中,// = require jquery.csrf无法正常工作,对吧?相反,我在其中使用了导入“ jquery.csrf”的pack js文件。请注意,您无需在视图中包含带有pack标签的标签。
– Damien JustinŠutevski
17年5月13日在2:34
#13 楼
如果您将JavaScript与jQuery结合使用以生成表单中的令牌,则可以使用以下方法:<input name="authenticity_token"
type="hidden"
value="<%= $('meta[name=csrf-token]').attr('content') %>" />
显然,您需要在Ruby布局中使用
<%= csrf_meta_tag %>
。#14 楼
对于确实需要非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();
评论
这不使用jQuery作为选择器吗?
–尤尔
15年6月29日在15:19
#15 楼
我为这个问题苦苦挣扎了好几天。任何GET调用均正常运行,但是所有PUT都会生成“无法验证CSRF令牌真实性”错误。我的网站运行良好,直到我向nginx添加了SSL证书。我终于在nginx设置中偶然发现了此缺失的行:
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto https; # Needed to avoid 'WARNING: Can't verify CSRF token authenticity'
proxy_pass http://puma;
}
添加缺少的行“ proxy_set_header X-Forwarded-Proto https;”后,我所有的CSRF令牌错误都退出了。
希望这可以帮助其他人也将自己的头撞在墙上。哈哈
#16 楼
如果有人需要与Uploadify和Rails 3.2相关的帮助(当我在这篇文章上搜索时像我一样),此示例应用程序可能会有所帮助:https://github.com/n0ne/Uploadify-Carrierwave-Rails-3.2.3 /blob/master/app/views/pictures/index.html.erb
还请检查此应用程序中的控制器解决方案
#17 楼
我正在使用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
是显示正在设置的标头(尽管不需要使用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
最后由于我切换了cookie而失败了关。如果未启用Cookie,CSRF将无法工作,因此,如果您看到此错误,则这是另一个可能的原因。
评论
这非常有帮助!
–黄乔
18/12/26在8:27
评论
布局标题中是否有<%= csrf_meta_tag%>?是这样的:<%= csrf_meta_tags%>
您有提供ajax客户端功能的jquery-rails库吗?
而HAML方式是添加“ = csrf_meta_tags”
好问题,谢谢提问。