关于rails上的ruby:ActionController :: InvalidAuthenticityToken

ActionController::InvalidAuthenticityToken

以下是由"我的Rails"应用程序中的一个表单导致的错误:

1
2
3
4
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就在那里。


我也有同样的问题,但是页面被缓存了。页面使用过时的真实性令牌进行缓冲,所有操作都使用方法post/put/delete(识别为伪造尝试)。向用户返回错误(422个不可处理的实体)。

解决方案:添加:

1
 skip_before_filter :verify_authenticity_token

或者正如Rails 4中指出的"Sagivo",添加:

1
 skip_before_action :verify_authenticity_token

在执行缓存的页面上。

正如@toobulkeh所评论的那样,这不是:index:show动作的漏洞,但要注意在:put:post动作上使用它。

例如:

1
2
 caches_page :index, :show  
 skip_before_filter :verify_authenticity_token, :only => [:index, :show]

参考:http://api.rubyonrails.org/classes/actioncontroller/requestforgeryprotection/classmethods.html


对我来说,Rails 4下的这个问题的原因是丢失了,

1
<%= csrf_meta_tags %>

主应用程序布局中的行。我重写布局时不小心把它删除了。

如果这不在主布局中,您将需要它在您想要CSRF令牌的任何页面中。


此错误有几个原因(与Rails 4相关)。1。检查页面布局中存在的EDOCX1[6]2。如果使用带remote: true选项的form_for助手,则使用ajax调用发送check authority令牌。如果不使用,则可以在表单块中包含行<%= hidden_field_tag :authenticity_token, form_authenticity_token %>。三。如果从缓存的页面发送请求,则使用片段缓存来排除发送请求的部分页面,如button_to等,否则令牌将过时/无效。

我不愿意取消CSRF保护…


真实性令牌是在您的视图中生成的一个随机值,用于证明请求是从您的站点上的表单提交的,而不是从其他地方提交的。这可以防止CSRF攻击:

http://en.wikipedia.org/wiki/cross-site_request_forgery

检查看看这个客户机/IP是谁,看起来他们在使用您的站点而不加载您的视图。

如果您需要进一步调试,这个问题是一个很好的开始:了解Rails真实性令牌

编辑解释:这意味着他们调用操作来处理表单提交,而不必在网站上呈现表单。这可能是恶意的(比如发布垃圾邮件评论),也可能表示客户试图直接使用您的Web服务API。你是唯一能够根据你的产品的性质和分析你的要求来回答这个问题的人。


只需在表单中添加EDOCX1[0]就可以为我修复它。

1
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>


回答太晚了,但我找到了解决办法。

定义自己的HTML表单时,由于安全原因,缺少应发送到控制器的身份验证令牌字符串。但是当您使用Rails表单帮助器生成表单时,会得到如下的结果

1
2
3
4
5
6
7
8
9
10
<form accept-charset="UTF-8" action="/login/signin" method="post">
 
    <input name="utf8" type="hidden" value="&#x2713;">
    <input name="authenticity_token" type="hidden"
      value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA=">
    .
    .
    .
 
</form>

因此,解决这个问题的方法要么是添加authority_token字段,要么使用rails表单帮助器,而不是删除、降级或升级rails。


ActionController::InvalidAuthenticityToken也可能由配置错误的反向代理引起。如果在堆栈跟踪中,您得到一条类似于Request origin does not match request base_url的线,则会出现这种情况。

当使用反向代理(如nginx)作为https请求的接收者并将未加密的请求传输到后端(如rails app)时,后端(更具体地说:rack)希望一些头文件包含有关原始客户端请求的更多信息,以便能够应用各种处理任务和安全措施。

更多详情请访问:https://github.com/rails/rails/issues/22965。

tl;dr:解决方案是添加一些头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}


如果你做过rake rails:update或者最近更改过config/initializers/session_store.rb,这可能是浏览器中老cookie的症状。希望这是在dev/test中完成的(对我来说),并且您可以清除所有与相关域相关的浏览器cookie。

如果这是在生产中,而您更改了key,请考虑将其改回使用旧的cookie(只是猜测)。


我对javascript调用有这个问题。我修正了这个问题,只需要jquery_ujs到application.js文件中。


对于Rails 5,最好添加protect_from_forgery prepend: true而不是跳过verify_authentication_token


我们有同样的问题,但注意到它只适用于使用http://的请求,而不适用于https://。原因是会话存储的secure: true

1
2
3
4
5
6
Rails.application.config.session_store(
  :cookie_store,
  key: '_foo_session',
  domain: '.example.com',
  secure: true
)

通过使用https~无处不在修复:)


添加

1
//= require rails-ujs

在里面

1
\app\assets\javascripts\application.js

我有这个问题,原因是我复制并粘贴了一个控制器到我的应用程序。我需要把ApplicationController改成ApplicationController::Base


我在本地主机上也有同样的问题。我已经更改了应用程序的域,但是在URL和主机文件中仍然有旧域。更新了我的浏览器书签和主机文件以使用新域,现在一切正常。


也许你的nginx设置为https,但你的证书无效?我以前也遇到过类似的问题,从HTTP重定向到HTTPS解决了这个问题。


我已经检查了<%=csrf_meta_tags%>是否存在,并且清除浏览器中的cookies对我很有用。


根据ChromeLighthouse对更快应用程序加载的建议,我已经异步了我的javascript:

埃多克斯1〔5〕

1
<%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload', async: true %>

这破坏了一切,并为我的远程表单带来了令牌错误。删除async: true解决了问题。


安装

1
gem 'remotipart'

可以帮助


问题从2.3.8降到2.3.5。(以及臭名昭著的"你被重新定向了。"问题)