以下是由我的Rails应用程序中的表单引起的错误:
Processing UsersController#update (for **ip** at 2010-07-29 10:52:27) [PUT]
Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"ysiDvO5s7qhJQrnlSR2+f8jF1gxdB7T9I2ydxpRlSSk=", **more parameters**}
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
对于每个非get
请求都会发生这种情况,正如您所见,authenticity_token
就在那里。
答案 0 :(得分:189)
我遇到了同样的问题但页面缓存了页面。页面使用陈旧的真实性令牌进行缓冲,并使用post / put / delete方法将所有操作识别为伪造尝试。错误(422 Unprocessable Entity)已返回给用户。
解决方案:
添加:
skip_before_filter :verify_authenticity_token
或者作为“sagivo”在Rails 4中指出:
skip_before_action :verify_authenticity_token
在进行缓存的页面上。
正如@toobulkeh评论说,这不是:index
,:show
操作的漏洞,但要注意:put
,:post
行为。
例如:
caches_page :index, :show
skip_before_filter :verify_authenticity_token, :only => [:index, :show]
参考:http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html
答案 1 :(得分:72)
对我来说,Rails 4下这个问题的原因是遗漏了,
<%= csrf_meta_tags %>
在我的主应用程序布局中排队。当我重新编写布局时,我意外地删除了它。
如果这不在主布局中,您将需要在任何您想要CSRF令牌的页面中。
答案 2 :(得分:54)
导致此错误的原因有多种,(与Rails 4有关)。
1.检查页面布局中的<%= csrf_meta_tags %>
2。如果使用带有form_for
选项的remote: true
帮助程序,则使用AJAX调用发送检查真实性令牌。如果不是,则可以包含带有表单块的行<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
。
3。如果要求从缓存页面发送请求,请使用fragment caching排除发送请求的部分页面,例如button_to
等,否则令牌将失效/无效。
我不愿意废除csrf保护......
答案 3 :(得分:29)
真实性令牌是在您的视图中生成的随机值,用于证明请求是从您网站上的表单提交的,而不是在其他地方提交的。这可以防止CSRF攻击:
http://en.wikipedia.org/wiki/Cross-site_request_forgery
检查该客户端/ IP是谁,看起来他们正在使用您的网站而不加载您的观点。
如果您需要进一步调试,这个问题是一个很好的起点:Understanding the Rails Authenticity Token
编辑解释: 这意味着他们正在调用处理您的表单提交的操作,而不会在您的网站上呈现您的表单。这可能是恶意的(比如发布垃圾评论),也可能表示客户试图直接使用您的Web服务API。您是唯一一个能够根据产品性质和分析您的要求来回答问题的人。
答案 4 :(得分:27)
只需在表格中添加authenticity_token
即可。
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
答案 5 :(得分:16)
回答太迟了,但我找到了解决方案。
当您定义自己的html表单时,您会错过应出于安全原因发送到控制器的身份验证令牌字符串。但是当你使用rails form helper来生成表单时,你会得到类似下面的内容
<form accept-charset="UTF-8" action="/login/signin" method="post">
<div style="display:none">
<input name="utf8" type="hidden" value="✓">
<input name="authenticity_token" type="hidden"
value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA=">
.
.
.
</div>
</form>
因此问题的解决方案是添加authenticity_token字段或使用rails form helper而不是删除,降级或升级rails。
答案 6 :(得分:11)
ActionController::InvalidAuthenticityToken
也可能是由反向代理配置错误引起的。如果在堆栈跟踪中得到的行看起来像Request origin does not match request base_url
,就属于这种情况。
当使用反向代理(例如nginx)作为HTTPS请求的接收者并将未加密的请求传输到后端(例如Rails应用)时,后端(更具体地说:Rack)需要一些标头,其中包含有关原始客户请求,以便能够应用各种处理任务和安全措施。
此处有更多详细信息:https://github.com/rails/rails/issues/22965。
TL; DR:解决方案是添加一些标头:
upstream myapp {
server unix:///path/to/puma.sock;
}
...
location / {
proxy_pass http://myapp;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on; # Optional
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $host;
}
答案 7 :(得分:6)
如果您已完成rake rails:update
或最近更改了config/initializers/session_store.rb
,则可能是浏览器中旧Cookie的症状。希望这是在dev / test(它适合我)中完成的,您可以清除与相关域相关的所有浏览器cookie。
如果这是在制作中,并且您更改了key
,请考虑将其更改为使用旧的Cookie(&lt; - 只是推测)。
答案 8 :(得分:4)
我在javascript调用时遇到了这个问题。我修复了这一点,只需要将jquery_ujs放入application.js文件中。
答案 9 :(得分:2)
对于rails 5,最好添加
protect_from_forgery prepend: true
而不是跳过verify_authentication_token
答案 10 :(得分:1)
我们遇到了同样的问题,但发现它只适用于使用http://且不使用https://的请求。对于session_store,原因是secure: true
:
Rails.application.config.session_store(
:cookie_store,
key: '_foo_session',
domain: '.example.com',
secure: true
)
使用HTTPS~无处不在修复:)
答案 11 :(得分:0)
这个答案更特定于Ruby on Rails,但希望它能对某人有所帮助。
您需要在每个非GET请求中包含CSRF令牌。如果您习惯使用JQuery,Rails会提供一个名为jquery-ujs
的帮助程序库,该程序库建立在它的基础上并添加了一些隐藏的功能。它要做的一件事是在每个ajax
请求中自动包含CSRF令牌。 See here。
如果像我一样离开它,可能会发现自己出错。您可以只手动提交令牌,也可以使用其他库来帮助从DOM刮取令牌。有关更多详细信息,请参见this post。
答案 12 :(得分:0)
我在 Rails 6 中遇到了类似的错误。尝试了上述解决方案后,我进行了表单审查,发现我在表单中使用了 <button>.....</button>
HTML 标记,而不是通过 Rails 提交
答案 13 :(得分:0)
在Rails 5中,我们需要添加两行代码
skip_before_action :verify_authenticity_token
protect_from_forgery prepend: true, with: :exception
答案 14 :(得分:0)
对于开发环境,我在Rails 6中尝试了许多尝试来解决此问题。它们都没有帮助。因此,如果这些建议都不适合您,请尝试以下操作。
我发现的唯一解决方案是将txt文件添加到您的/ tmp文件夹中。
在应用的根目录中,运行:
touch tmp/caching-dev.txt
或在/ tmp文件夹中以该名称手动创建文件。由于此问题已为我解决,因此我认为问题的根源是缓存冲突。
答案 15 :(得分:0)
在我的控制台中运行rails dev:cache
可以解决此问题! (第6条)
我认为这可能与Turbolinks有关,但是CSRF仅在启用 的本地缓存时才起作用。
答案 16 :(得分:0)
在对我的应用程序的注册过程进行手动测试(与多个用户注册/登录)时,这发生在我身上。
一个非常简单实用的解决方案可能是做我所做的事情,并使用其他浏览器(如果使用chrome,则使用隐身浏览器。)
与禁用安全功能相比,在我看来,这是一个 很多 更好的解决方案!
答案 17 :(得分:0)
从Rails 4.0升级到4.2时,这发生在我身上。
verified_request?
的4.2实现看request.headers['X-CSRF-Token']
,而我的4.0应用程序获得的标头是X-XSRF-TOKEN
。我的ApplicationController中的一个快速修复是添加函数:
def verify_authenticity_token
request.headers['X-CSRF-Token'] ||= request.headers['X-XSRF-TOKEN']
super
end
答案 18 :(得分:0)
添加
//= require rails-ujs
在
\app\assets\javascripts\application.js
答案 19 :(得分:0)
为了获得更快的应用程序加载速度,遵循了Chrome Lighthouse建议,我已同步了Javascript:
views/layout/application.html.erb
<%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload', async: true %>
这破坏了一切,并在我的远程表单中出现了Token错误。删除async: true
可以解决此问题。
答案 20 :(得分:0)
我已经检查了<%= csrf_meta_tags%>是否存在,并且清除浏览器中的cookie对我有用。
答案 21 :(得分:0)
也许您的HTTPS设置了NGINX,但您的证书无效? 我过去遇到过类似的问题,从http重定向到https解决了问题
答案 22 :(得分:0)
我在localhost上遇到了同样的问题。我已经更改了应用程序的域名,但在URL和hosts文件中仍然存在旧域名。更新了我的浏览器书签和托管文件以使用新域名,现在一切正常。
答案 23 :(得分:0)
安装
gem 'remotipart'
可以提供帮助
答案 24 :(得分:0)
我遇到了这个问题,原因是因为我将控制器复制并粘贴到我的应用中。我需要将ApplicationController
更改为ApplicationController::Base
答案 25 :(得分:-10)
通过从2.3.8降级到2.3.5解决了问题。 (以及臭名昭着的'你被重定向。'问题)