ActionController的:: InvalidAuthenticityToken

时间:2010-07-29 15:57:45

标签: ruby-on-rails

以下是由我的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就在那里。

26 个答案:

答案 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="&#x2713;">
    <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 提交

{ {2}} 表单助手。更改为表单助手解决了该问题。

答案 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解决了问题。 (以及臭名昭着的'你被重定向。'问题)