的ActionController :: InvalidAuthenticityToken

问题描述:

下面是一个错误,在我的Rails应用程序引起的一种形式:的ActionController :: InvalidAuthenticityToken

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是存在的。

问题由从2.3.8降级到2.3.5解决。 (以及臭名昭著的“您将被重定向。”的问题)

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

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

检查,检查客户端/ IP是谁,它看起来像他们使用你的网站,而无需加载你的看法。

如果您需要进一步调试,这个问题是一个良好的开端:Understanding the Rails Authenticity Token

编辑解释: 这意味着他们调用的行动来处理您提交表单而没有呈现在您的网站表单。这可能是恶意的(比如说发布垃圾评论),或者它可能表明一位客户试图直接使用您的Web服务API。您是唯一能够根据您的产品性质来回答此问题并分析您的请求的人。

+0

谢谢,但我已经知道什么是真实性标记。 _查看谁是客户端/ IP,看起来他们正在使用您的网站而不加载您的views._对不起,“没有加载意见”是什么意思? – 2010-07-29 16:20:06

+1

我的意思是有人(可能是垃圾邮件发送者)可能会将数据提交到您的表单,而无需通过您的应用程序的用户界面。例如,可以使用诸如curl之类的命令行程序来执行此操作。 – 2010-07-29 16:32:33

+0

约翰完全正确。这意味着他们正在调用处理表单提交的操作,而无需在您的网站上呈现您的表单。 这可能是恶意的(比如说发布垃圾评论),或者它可能表明客户试图直接使用您的Web服务API。 您是唯一可以根据您的产品性质和分析您的请求来回答问题的人。 – Winfield 2010-07-29 16:35:13

我有同样的问题,但页面缓存的页面。页面被缓存了一个陈旧的真实性标记,并且所有使用方法post/put/delete的操作被识别为伪造企图。错误(422不可处理实体)已返回给用户。

解决办法:
地址:

skip_before_filter :verify_authenticity_token 

或 “sagivo” 在轨道4,5加指出:

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

+3

这不太可能,我不知道_caches_page_在发布之前。但是我会检查_caches_page_,谢谢。 – 2010-08-30 18:01:33

+7

in rails 4'skip_before_action:verify_authenticity_token' – 2014-02-27 17:48:24

+58

这不是一个漏洞吗? – quantumpotato 2014-11-24 04:40:37

对我来说,下轨道4这个问题的原因是我的主要的应用程序布局的缺失,

<%= csrf_meta_tags %> 

线。当我重写我的布局时,我意外删除了它。

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

+0

非常好!解决了我的问题 – Jason 2014-11-15 21:27:57

+0

我们也收到此错误。但它是中断的。这可能是原因或不会影响每个请求的错误? – 2015-10-01 14:21:52

+0

@ Ryan-NealMes,如果你的模板缺少该行,你会得到错误。所以有可能你的一些模板有它,其他的则没有。 – 2015-10-01 21:02:38

我有这个问题与JavaScript调用。我解决了这个问题,只需要jquery_ujs到application.js文件中。

+0

是的,我也有这个问题,我在应用程序js中添加了jquery_ujs。有效。 – Abhi 2017-08-03 05:38:07

来不及回答,但我找到了解决方案。

当你定义你自己的html表单时,你会因为安全原因而错过应该发送给控制器的认证令牌字符串。但是,当你使用轨道形成辅助函数生成表单你喜欢的东西下面

<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场或使用轨道形成的助手而不是删除,降级或升级的轨道。

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

导致此错误的原因有几个(涉及Rails 4)。如果使用form_for佣工remote: true option.If不是你可以包括withing形式块行<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

1.检查<%= csrf_meta_tags %>出现在页面布局

2.检查真实性令牌正在使用AJAX调用发送。

3.如果正在从缓存页面发送请求,请使用fragment caching排除发送请求的部分页面,例如button_to等,否则令牌将陈旧/无效。

我就不愿废除CSRF保护...

如果你已经做了rake rails:update或以其他方式最近改变了你的config/initializers/session_store.rb,这可能是旧的饼干的症状在浏览器中。希望这是在开发/测试(这是为我)完成的,你可以清除所有浏览器相关的cookies的问题。

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

安装

gem 'remotipart' 

可以帮助

+1

虽然这可能是答案,但它也有助于包括答案的重要部分,并解释为什么/如何工作。 – Roylee 2015-11-16 02:52:32

我们有同样的问题,但发现它是只使用HTTP请求://,而不是以https://。原因是secure: true为session_store:

Rails.application.config.session_store(
    :cookie_store, 
    key: '_foo_session', 
    domain: '.example.com', 
    secure: true 
) 

固定使用HTTPS〜处处:)

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

只需在表格中添加authenticity_token即可。

<%= hidden_field_tag :authenticity_token, form_authenticity_token %> 
+1

Rails应该默认发送令牌。我们不想明确指定它。在这种情况下,我感觉令牌有所改变。 – Abhi 2017-08-03 05:06:09

也许您已将您的NGINX设置为HTTPS,但您的证书无效? 我以前有类似的问题,并从http重定向到https解决了问题

我已经使用过这样的东西,它适用于我。

class WelcomeController < ActionController::Base 
    protect_from_forgery with: :exception 
    before_action :authenticate_model! 
end