Rails4 ActionController :: InvalidAuthenticityToken错误

bbb*_*oon 17 ruby-on-rails ruby-on-rails-4

我有Rails4应用程序在生产中运行,我的访问者偶尔运行到ActionController :: InvalidAuthenticityToken错误,我无法重现.我从各种表格收到每日2-4次通知,背后没有明确的逻辑.我收到的报告显示,表单提交的authenticity_token与会话中保存的不同.这怎么可能?我设法自己遇到问题几次,但是无法重现,表单的所有突然的authenticity_token都与会话中存储的不同,并且出现了InvalidAuthenticityToken.
任何想法从哪里开始寻找?

例:

 Request:
-------------------------------

  * URL        : https://domain/signin
  * HTTP Method: POST
  * IP address : 113.96.xx.xx
  * Parameters : {"utf8"=>"?", "authenticity_token"=>"MOh9JDE1AZ0CbIw/M33vfhjRShwzI6oqMhi8lk+n7OE=", "email"=>"xxxx@xxx", "password"=>"[FILTERED]", "commit"=>"Sign In", "controller"=>"clients", "action"=>"signin", "locale"=>"en"}

-------------------------------
Session:
-------------------------------

  * session id: [FILTERED]
  * data: {"_csrf_token"=>"QazCSVGeZlxEh83XTM+f5PkC/zopwCF96yV4duRats0="}
Run Code Online (Sandbox Code Playgroud)

更新:想要添加我通过两个负载均衡的AWS EC2实例为页面提供服务,并在Redis ElastiCache实例中存储会话

Jas*_*abe 16

Rails生成的任何表单(即使用form_for和不使用<form>此模板)都会在必要时将反CSRF令牌添加为隐藏字段.如果您自己编写表单并且未包含CSRF隐藏输入,那么Rails依赖于CSRF元标记和JavaScript来实现工作.因此,如果您编写了自己的表单并且未包含隐藏字段,并且如果客户端的JavaScript因任何原因无效,则可能会出现此错误.因为"客户端的JavaScript不能用于任何原因"是一个很难检测和调试的子句,所以我实际上故意删除了我网站上的CSRF元标记.这样,如果我忘记包含隐藏的输入,它将为每个人打破(快速失败),我会立即发现它,我可以解决它.我建议你也这样做.

话虽如此,我建议您查看这些"访问者"的访问日志.你觉得奇怪吗?

  • 他们是否在提交之前立即访问包含该表单的页面?如果没有,也许他们是机器人或实际的,实际的CSRF尝试(这是检查的,不是吗?:)).
  • 他们是否在一个EC2上加载表格并最终提交给另一个?如果是这样,你可以关闭一个EC2,看看错误是否消失?
  • 他们以某种方式失去了会话吗?这可能是你的问题或他们的问题.

  • 好吧,如果令牌丢失了,我想我的params中根本就没有"authenticity_token",而不是错误的. (2认同)

bbb*_*oon 4

为了回答我自己的问题,如果有人遇到同样的问题,似乎从标头中删除 csrf_meta_tag 解决了我们的问题。我不知道为什么。可能是负责设置 auth_token 的 Rails javascript 以某种方式干扰了我们的 javascript 并导致了问题,但我的直觉是它必须在服务器端或客户端上进行缓存。不管怎样,删除 csrf_meta_tag 后,我们似乎解决了这个问题。只需确保您在所有表单中使用 form_tag 即可。