警告:无法验证 CSRF 令牌真实性
我使用 AJAX 将数据从视图发送到控制器,但收到此错误:
警告:无法验证 CSRF 令牌的真实性
我想我必须将此令牌与数据一起发送。
有谁知道我该怎么做?
编辑:我的解决方案
我通过将以下代码放入 AJAX 帖子中来做到这一点:
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
您应该执行以下操作:
确保您的布局中有
<%= csrf_meta_tag %>
将
beforeSend
添加到所有 ajax 请求以设置标头,如下所示:要在所有请求中发送令牌,您可以使用:
You should do this:
Make sure that you have
<%= csrf_meta_tag %>
in your layoutAdd
beforeSend
to all the ajax request to set the header like below:To send token in all requests you can use:
最好的方法实际上是使用
<%= form_authenticity_token.to_s %>
直接在 Rails 代码中打印出令牌。您不需要像其他帖子提到的那样使用 javascript 在 dom 中搜索 csrf 令牌。只需添加标题选项,如下所示;The best way to do this is actually just use
<%= form_authenticity_token.to_s %>
to print out the token directly in your rails code. You dont need to use javascript to search the dom for the csrf token as other posts mention. just add the headers option as below;如果我没记错的话,您必须将以下代码添加到您的表单中,以解决此问题:
不要忘记参数。
If I remember correctly, you have to add the following code to your form, to get rid of this problem:
Don't forget the parameter.
确实是最简单的方法。不必费心更改标题。
确保你有:
只需像这样创建一个隐藏的输入字段:
或者如果你想要一个 jQuery ajax 帖子:
Indeed simplest way. Don't bother with changing the headers.
Make sure you have:
Just do a hidden input field like so:
Or if you want a jQuery ajax post:
从较旧的应用程序升级到 Rails 3.1(包括 csrf 元标记)仍然无法解决问题。在 rubyonrails.org 博客上,他们提供了一些升级提示,特别是这行 jquery 应该放在布局的头部:
摘自此博客文章:http://weblog.rubyonrails.org/2011/2/8/ csrf-protection-bypass-in-ruby-on-rails。
就我而言,每次 ajax 请求时都会重置会话。添加上面的代码解决了这个问题。
Ugrading from an older app to rails 3.1, including the csrf meta tag is still not solving it. On the rubyonrails.org blog, they give some upgrade tips, and specifically this line of jquery which should go in the head section of your layout:
taken from this blog post: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails.
In my case, the session was being reset upon each ajax request. Adding the above code solved that issue.
<%= csrf_meta_tag %>
beforeSend
以在 ajax 请求中包含 csrf-token 以设置标头。这仅对于post
请求是必需的。读取 csrf-token 的代码可以在
rails/jquery-ujs
中找到,所以恕我直言,使用它是最简单的,如下所示:<%= csrf_meta_tag %>
in your layoutbeforeSend
to include the csrf-token in the ajax request to set the header. This is only required forpost
requests.The code to read the csrf-token is available in the
rails/jquery-ujs
, so imho it is easiest to just use that, as follows:这里投票最高的答案是正确的,但如果您执行跨域请求,则该答案将不起作用,因为除非您明确告诉 jQuery 传递会话 cookie,否则会话将不可用。具体做法如下:
The top voted answers here are correct but will not work if you are performing cross-domain requests because the session will not be available unless you explicitly tell jQuery to pass the session cookie. Here's how to do that:
我只是想将其链接到此处,因为这篇文章包含您正在寻找的大部分答案,而且也非常有趣
http://www.kalzumeus.com/2011/11/17/i-saw-an-extremely-subtle-bug-today-and-i-just-have-to-tell-someone/
I just thought I'd link this here as the article has most of the answer you're looking for and it's also very interesting
http://www.kalzumeus.com/2011/11/17/i-saw-an-extremely-subtle-bug-today-and-i-just-have-to-tell-someone/
您可以像下面这样全局编写它。
普通 JS:
咖啡脚本:
You can write it globally like below.
Normal JS:
Coffee Script:
如果您不使用 jQuery 并使用类似 fetch API 的请求,您可以使用以下方法获取 <代码>csrf-token:
document.querySelector('meta[name="csrf-token"]').getAttribute('content')
If you are not using jQuery and using something like fetch API for requests you can use the following to get the
csrf-token
:document.querySelector('meta[name="csrf-token"]').getAttribute('content')
哎呀..
我在 application.js 中错过了以下行,
我替换了它并使其正常工作..
======= 更新 =========
5 年后,我又回来了,现在出现同样的错误我有全新的Rails 5.1.6,我又发现了这篇文章。就像生命的轮回一样。
现在的问题是:
Rails 5.1 默认情况下删除了对 jquery 和 jquery_ujs 的支持,并添加了
它执行以下操作:
(来自: https://github.com/rails/rails-ujs/tree/master )
但是为什么它不包含ajax请求的csrf令牌呢?如果有人详细了解这一点,请评论我。我很欣赏这一点。
无论如何,我在自定义 js 文件中添加了以下内容以使其正常工作(感谢其他答案帮助我实现此代码):
oops..
I missed the following line in my application.js
I replaced it and its working..
======= UPDATED =========
After 5 years, I am back with Same error, now I have brand new Rails 5.1.6, and I found this post again. Just like circle of life.
Now what was the issue is:
Rails 5.1 removed support for jquery and jquery_ujs by default, and added
It does the following things:
(from: https://github.com/rails/rails-ujs/tree/master)
But why is it not including the csrf token for ajax request? If anyone know about this in detail just comment me. I appreciate that.
Anyway I added the following in my custom js file to make it work (Thanks for other answers to help me reach this code):
使用 jquery.csrf (https://github.com/swordray/jquery.csrf)。
Rails 5.1 或更高版本
Rails 5.0 或更低版本
源代码
<前><代码>(函数($) {
$(文档).ajaxSend(函数(e, xhr, 选项) {
var token = $('meta[name="csrf-token"]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
});
})(jQuery);
Use jquery.csrf (https://github.com/swordray/jquery.csrf).
Rails 5.1 or later
Rails 5.0 or before
Source code
如果您使用 javascript 和 jQuery 在表单中生成令牌,则此方法有效:
显然,您需要在 Ruby 布局中包含
<%= csrf_meta_tag %>
。If you're using javascript with jQuery to generate the token in your form, this works:
Obviously, you need to have the
<%= csrf_meta_tag %>
in your Ruby layout.我为这个问题苦苦挣扎了好几天。任何 GET 调用都可以正常工作,但所有 PUT 都会生成“无法验证 CSRF 令牌真实性”错误。在我向 nginx 添加 SSL 证书之前,我的网站工作正常。
我终于在 nginx 设置中偶然发现了这个缺失的行:
添加缺失的行“proxy_set_header X-Forwarded-Proto https;”后,我所有的 CSRF 令牌错误都会退出。
希望这可以帮助其他同样在墙上碰头的人。哈哈
I struggled with this issue for days. Any GET call was working correctly, but all PUTs would generate a "Can't verify CSRF token authenticity" error. My website was working fine until I had added a SSL cert to nginx.
I finally stumbled on this missing line in my nginx settings:
After adding the missing line "proxy_set_header X-Forwarded-Proto https;", all my CSRF token errors quit.
Hopefully this helps someone else who also is beating their head against a wall. haha
如果有人需要与 Uploadify 和 Rails 3.2 相关的帮助(就像我在 google 上搜索这篇文章时一样),这个示例应用程序可能会有所帮助:
https:// /github.com/n0ne/Uploadify-Carrierwave-Rails-3.2.3/blob/master/app/views/pictures/index.html.erb
还检查此中的控制器解决方案 应用程序
if someone needs help related with Uploadify and Rails 3.2 (like me when I googled this post), this sample app may be helpful:
https://github.com/n0ne/Uploadify-Carrierwave-Rails-3.2.3/blob/master/app/views/pictures/index.html.erb
also check the controller solution in this app
对于那些确实需要非 jQuery 答案的人,您可以简单地添加以下内容:
这里可以提供一个非常简单的示例:
For those of you that do need a non jQuery answer you can simple add the following:
A very simple example can be sen here:
我正在使用 Rails 4.2.4,无法弄清楚为什么我得到:
我在布局中:
在控制器中:
显示调用
tcpdump -A -s 999 -i lo port 3000
正在设置的标头(尽管不需要使用ajaxSetup
设置标头 - 它已经完成了):最后它失败了,因为我关闭了cookie。如果不启用 cookie,CSRF 将无法工作,因此如果您看到此错误,这是另一个可能的原因。
I'm using Rails 4.2.4 and couldn't work out why I was getting:
I have in the layout:
In the controller:
Invoking
tcpdump -A -s 999 -i lo port 3000
was showing the header being set ( despite not needing to set the headers withajaxSetup
- it was done already):In the end it was failing because I had cookies switched off. CSRF doesn't work without cookies being enabled, so this is another possible cause if you're seeing this error.
2023 年升级到 Rails 7 后,由于某种原因我遇到了这个问题。也许我正在使用普通的 jQuery,而不是 jQuery 的某些 Rails 变体,或者任何“UJS”。
通过将其添加到我的页面特定的 Javascript 代码中来修复它:(
我的 html 布局顶部已经有
<%= csrf_meta_tags %>
)我正常的 jQuery Ajax 代码如下所示:
After upgrading to Rails 7 in 2023, I had this issue for some reason. Perhaps I'm using normal jQuery instead of some rails variant of jQuery, or whatever "UJS" is.
Fixed it by adding this to my page-specific Javascript code:
(I already had
<%= csrf_meta_tags %>
at the top of my html layout)My normal jQuery Ajax code looks like:
进行 API 调用时缺少 CSRF 令牌。您可以在标头中发送“X-CSRF-Token”。
[name=""csrf-token""] 是可以获取令牌的 html 元素。
CSRF token is missing while making API call. You can send ""X-CSRF-Token"" in the headers.
[name=""csrf-token""] is the html element where you can get the token.