Ruby on rails 不应该';t使用::exception防止伪造如果我没有';不包括真实性令牌?

Ruby on rails 不应该';t使用::exception防止伪造如果我没有';不包括真实性令牌?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我的理解是,使用::exception防止伪造,这是Rails中的默认设置,如果表单提交时没有真实性标记输入,则会导致错误 然而,情况似乎已经不是这样了。这是一个Rails 5应用程序,我过去主要做过Rails 4,所以我想知道是否有什么变化 在application\u controller.rb中,我使用::exception保护\u免受伪造 我的表格是这样的(使用slim) 我眼中的主要问题是为什么这不会引起错误。在过去,我必须包含一个隐藏的输入,其值为form\u authencity\

我的理解是,
使用::exception
防止伪造,这是Rails中的默认设置,如果表单提交时没有
真实性标记
输入,则会导致错误

然而,情况似乎已经不是这样了。这是一个Rails 5应用程序,我过去主要做过Rails 4,所以我想知道是否有什么变化

在application\u controller.rb中,我使用::exception保护\u免受伪造

我的表格是这样的(使用slim)


我眼中的主要问题是为什么这不会引起错误。在过去,我必须包含一个隐藏的输入,其值为
form\u authencity\u token

检查表单时,表单上是否有真实性标记?您的应用程序中插入了哪一点
防止伪造


Rails 4=>5更改了默认行为,将其插入到调用它的链中的任何位置,而不是之前首先调用它的位置。如果您希望在任何其他操作之前调用它,请尝试使用
prepend:true
标志。

我认为这与Rails 5更改了
防止伪造
执行顺序有关。由此

什么

如果我们在Rails 4.x中生成一个全新的Rails应用程序,那么
application\u controller
将如下所示

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end
在上述情况下,即使在
load\u user
之后进行了protect\u from\u forgery调用,保护还是首先执行。我们对此无能为力。我们无法通过任何选项来阻止Rails这样做

Rails 5通过引入一个名为prepend的布尔选项来改变这种行为。此选项的默认值为
false
。它的意思是,现在
protect\u from\u fackery
按调用顺序执行。当然,这可以通过如下所示传递
prepend:true
来覆盖,现在保护调用将首先发生,就像Rails 4.x一样

上述代码在Rails 4.x中可能会失败,因为
保护\u免受伪造
,虽然在
:authenticate
之后调用,但实际上在它之前执行。因此,我们无法正确设置
@authenticated_by


而在Rails 5中,
protect\u from\u forgery
:authenticate
之后执行,如果身份验证是oauth,则跳过该验证

生成的HTML中没有真实性令牌<如我在问题中所述,代码>防止伪造
位于application\u controller.rb中。我尝试添加
prepend:true
,但没有效果。换句话说,谢谢,但这不起作用。非常感谢你的详细回答。不幸的是,
prepend:true
根本没有效果。我得再把它弄得一团糟。
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end
class ApplicationController < ActionController::Base
  before_action :load_user
  protect_from_forgery with: :exception
end
class ApplicationController < ActionController::Base
  before_action :load_user
  protect_from_forgery with: :exception, prepend: true
end
class ApplicationController < ActionController::Base
  before_action :authenticate
  protect_from_forgery unless: -> { @authenticated_by.oauth? }

  private
    def authenticate
      if oauth_request?
        # authenticate with oauth
        @authenticated_by = 'oauth'.inquiry
      else
        # authenticate with cookies
        @authenticated_by = 'cookie'.inquiry
      end
    end
end