Ruby-on-rails ActionController::InvalidAuthenticityToken

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3364492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:58:44  来源:igfitidea点击:

ActionController::InvalidAuthenticityToken

ruby-on-rails

提问by Nikita Rybak

Below is an error, caused by a form in my Rails application:

下面是一个错误,由我的 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):

This happens for every non-getrequest and, as you see, authenticity_tokenis there.

对于每个非get请求都会发生这种情况,并且如您所见,authenticity_token就在那里。

采纳答案by Nikita Rybak

Problem solved by downgrading to 2.3.5 from 2.3.8. (as well as infamous 'You are being redirected.' issue)

通过从 2.3.8 降级到 2.3.5 解决了问题。(以及臭名昭著的“您正在被重定向。”问题)

回答by Szymon Je?

I had the same issue but with pages which were page cached. Pages got buffered with a stale authenticity token and all actions using the methods post/put/delete where recognized as forgery attempts. Error (422 Unprocessable Entity) was returned to the user.

我有同样的问题,但页面缓存了页面。页面被一个陈旧的真实性令牌缓冲,所有使用 post/put/delete 方法的操作都被识别为伪造尝试。错误 (422 Unprocessable Entity) 被返回给用户。

The solution for Rails 3:
Add:

Rails 3 的解决方案:
添加:

 skip_before_filter :verify_authenticity_token  

or as "sagivo" pointed out in Rails 4 add:

或者如 Rails 4 中指出的“sagivo”添加:

 skip_before_action :verify_authenticity_token

On pages which do caching.

在进行缓存的页面上。

As @toobulkeh commented this is not a vulnerability on :index, :showactions, but beware using this on :put, :postactions.

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

For example:

例如:

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

Reference: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

参考:http: //api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

Note added by barlop- Rails 4.2 deprecated skip_before_filter in favour of skip_before_action https://guides.rubyonrails.org/4_2_release_notes.html"The *_filter family of methods have been removed from the documentation. Their usage is discouraged in favor of the *_action family of methods"

barlop 添加的注释-Rails 4.2 不推荐使用 skip_before_filter 以支持 skip_before_action https://guides.rubyonrails.org/4_2_release_notes.html“*_filter 系列方法已从文档中删除。不鼓励使用 *_action方法族”

For Rails 6(as "collimarco" pointed out) you can use skip_forgery_protectionand that it is safe to use it for a REST API that doesn't use session data.

对于Rails 6(如“collimarco”指出的那样),您可以使用skip_forgery_protection并且将其用于不使用会话数据的 REST API 是安全的。

回答by James McMahon

For me the cause of this issue under Rails 4 was a missing,

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

<%= csrf_meta_tags %>

Line in my main application layout. I had accidently deleted it when I rewrote my layout.

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

If this isn't in the main layout you will need it in any page that you want a CSRF token on.

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

回答by GoodViber

There are several causes for this error, (relating to Rails 4).

1. Check <%= csrf_meta_tags %>present in page layout

2. check authenticity token is being sent with AJAX calls if using form_forhelper with remote: trueoption.If not you can include the line <%= hidden_field_tag :authenticity_token, form_authenticity_token %>withing the form block.

3. If request is being sent from cached page, use fragment cachingto exclude part of page that sends request e.g. button_toetc. otherwise token will be stale/invalid.

此错误有多种原因(与 Rails 4 相关)。

1. 检查<%= csrf_meta_tags %>页面布局中的存在

2. 如果使用form_for带有选项的帮助程序,检查是否通过 AJAX 调用发送真实性令牌。如果remote: true没有,您可以<%= hidden_field_tag :authenticity_token, form_authenticity_token %>在表单块中包含该行。

3. 如果请求是从缓存页面发送的,请使用片段缓存来排除发送请求的页面部分,例如button_to等。否则令牌将失效/无效。

I would be reluctant to nullify csrf protection...

我不愿意取消csrf保护......

回答by Deepak Mahakale

Just adding the authenticity_tokenin form fixed it for me.

只需添加authenticity_tokenin 表单即可为我修复它。

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

回答by Winfield

The authenticity token is a random value generated in your view to prove a request is submitted from a form on your site, not somewhere else. This protects against CSRF attacks:

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

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

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

Check to see who that client/IP is, it looks like they are using your site without loading your views.

检查该客户端/IP 是谁,看起来他们正在使用您的站点而没有加载您的视图。

If you need to debug further, this question is a good place to start: Understanding the Rails Authenticity Token

如果你需要进一步调试,这个问题是一个很好的起点:Understanding the Rails Authenticity Token

Edited to explain: It means they are calling the action to process your form submit without ever rendering your form on your website. This could be malicious (say posting spam comments) or it could indicate a customer trying to use your web service API directly. You're the only one who can answer that by the nature of your product and analyzing your requests.

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

回答by vmarquet

ActionController::InvalidAuthenticityTokencan also be caused by a misconfigured reverse proxy. This is the case if in the stack trace, you get a line looking like Request origin does not match request base_url.

ActionController::InvalidAuthenticityToken也可能是由错误配置的反向代理引起的。如果在堆栈跟踪中出现类似Request origin does not match request base_url.

When using a reverse proxy (such as nginx) as receiver for HTTPS request and transmitting the request unencrypted to the backend (such as the Rails app), the backend (more specifically: Rack) expects some headers with more information about the original client request in order to be able to apply various processing tasks and security measures.

当使用反向代理(例如 nginx)作为 HTTPS 请求的接收者并将未加密的请求传输到后端(例如 Rails 应用程序)时,后端(更具体地说:Rack)需要一些标头,其中包含有关原始客户端请求的更多信息以便能够应用各种处理任务和安全措施。

More details are available here: https://github.com/rails/rails/issues/22965.

此处提供更多详细信息:https: //github.com/rails/rails/issues/22965

TL;DR: the solution is to add some headers:

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;
}

回答by amjad

too late to answer but I found the solution.

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

When you define you own html form then you miss authentication token string that should be sent to controller for security reasons. But when you use rails form helper to generate a form you get something like following

当您定义自己的 html 表单时,您会错过出于安全原因应发送到控制器的身份验证令牌字符串。但是当您使用 rails 表单助手生成表单时,您会得到如下内容

<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>

So the solution to the problem is either to add authenticity_token field or use rails form helpers rather then removing , downgrading or upgrading rails.

所以问题的解决方案是添加authenticity_token 字段或使用rails 表单助手,而不是删除、降级或升级rails。

回答by kross

If you have done a rake rails:updateor otherwise recently changed your config/initializers/session_store.rb, this may be a symptom of old cookies in the browser. Hopefully this is done in dev/test (it was for me), and you can just clear all browser cookies related to the domain in question.

如果您做了rake rails:update或最近更改了您的config/initializers/session_store.rb,这可能是浏览器中旧 cookie 的症状。希望这是在开发/测试中完成的(它是给我的),并且您可以清除与相关域相关的所有浏览器 cookie。

If this is in production, and you changed key, consider changing it back to use the old cookies (<- just speculation).

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

回答by Michael Koper

I had this issue with javascript calls. I fixed that with just requiring jquery_ujs into application.js file.

我在 javascript 调用中遇到了这个问题。我只需要 jquery_ujs 到 application.js 文件中就解决了这个问题。

回答by Darep

We had the same problem, but noticed that it was only for requests using http:// and not with https://. The cause was secure: truefor session_store:

我们遇到了同样的问题,但注意到它仅适用于使用 http:// 而不是 https:// 的请求。原因是secure: truesession_store:

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

Fixed by using HTTPS ~everywhere :)

通过使用 HTTPS ~everywhere 修复:)