下面是一个错误,由我的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
.
我有同样的问题,但页面缓存页面.页面使用陈旧的真实性令牌进行缓冲,并使用post/put/delete方法将所有操作识别为伪造尝试.错误(422 Unprocessable Entity)已返回给用户.
解决方案:
添加:
skip_before_filter :verify_authenticity_token
或者像Rails 4中指出的"sagivo"一样:
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
对我来说,Rails 4下这个问题的原因是遗漏了,
<%= csrf_meta_tags %>
在我的主应用程序布局中排队.当我重写我的布局时,我意外地删除了它.
如果这不在主布局中,您将需要在任何您想要CSRF令牌的页面中.
导致此错误的原因有多种(与Rails 4相关).
1.检查<%= csrf_meta_tags %>
当前页面布局
2.如果使用带选项的form_for
帮助程序,则检查是否正在使用AJAX调用发送真实性令牌.如果remote: true
不是,则可以包含带有<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
表单块的行.
3.如果正在从缓存页面发送请求,则使用片段缓存来排除发送请求的页面的一部分,例如,button_to
否则令牌将陈旧/无效.
我不愿意取消csrf保护......
真实性令牌是在您的视图中生成的随机值,用于证明请求是从您网站上的表单提交的,而不是在其他地方提交的.这可以防止CSRF攻击:
http://en.wikipedia.org/wiki/Cross-site_request_forgery
检查客户端/ IP是谁,看起来他们正在使用您的网站而不加载您的视图.
如果您需要进一步调试,这个问题是一个很好的起点:了解Rails真实性令牌
编辑解释:这意味着他们正在调用处理您的表单提交的操作,而不会在您的网站上呈现您的表单.这可能是恶意的(比如发布垃圾评论),也可能表示客户试图直接使用您的Web服务API.您是唯一一个能够根据产品性质和分析您的要求来回答问题的人.
只需添加authenticity_token
in形式就可以修复它.
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
来不及回答,但我找到了解决方案.
当您定义自己的html表单时,您会错过应出于安全原因应发送到控制器的身份验证令牌字符串.但是当你使用rails form helper生成一个表单时,你会得到类似下面的内容
因此问题的解决方案是添加authenticity_token字段或使用rails form helper而不是删除,降级或升级rails.
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; }
如果您已完成rake rails:update
或最近更改了您的config/initializers/session_store.rb
,这可能是浏览器中旧cookie的症状.希望这是在dev/test(它适用于我)中完成的,您可以清除与相关域相关的所有浏览器cookie.
如果这是在生产中,并且您更改了key
,请考虑将其更改为使用旧cookie(< - 只是推测).
我在使用javascript调用时遇到了这个问题。我只需要将jquery_ujs放入application.js文件即可解决此问题。