protect_from_forgery - 顺序重要吗?

protect_from_forgery - does order matter?

我已经阅读了这个 post https://nvisium.com/blog/2014/09/10/understanding-protectfromforgery/ 如果我理解正确的话,默认情况下 Rails 3 如果我们有一个如下所示的控制器:

class ApplicationController < ActionController:Base
  protect_from_forgery
end

最终会发生的是(在攻击者的情况下)会话将被破坏。这意味着如果我们正在做一些事情,比如检查用户是否经过身份验证,因为没有会话,它将停止请求。

所以,我的问题是,我相信:

class ApplicationController < ActionController:Base
  protect_from_forgery
  before_action :authenticate_user

  private

  def authenticate_user
    raise NotAuthenticated unless session.key?(:user)
  end
end

是正确的做法,而不是

class ApplicationController < ActionController:Base
  before_action :authenticate_user
  protect_from_forgery

  private

  def authenticate_user
    raise NotAuthenticated unless session.key?(:user)
  end
end

或者换句话说,protect_from_forgery 应该是我们在控制器中做的第一件事。

我的假设是否正确,或者我遗漏了控制器中操作顺序的一些信息?

这两个方法的顺序并不重要,不。

原因与 何时 执行这些方法有关:这些是 Class 级别的方法,在 class 的上下文中执行Ruby 加载文件时本身。

查看 protect_from_forgery 的来源:

def protect_from_forgery(options = {})
  options = options.reverse_merge(prepend: false)

  self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session)
  self.request_forgery_protection_token ||= :authenticity_token
  before_action :verify_authenticity_token, options
  append_after_action :verify_same_origin_request
end

这些基本上是宏,当它们被调用时,会向您的 class 添加代码,这是一种元编程形式。您可以将 class 中的方法调用替换为手动设置这些内容,结果是一样的。

这一切都发生在您的代码首次加载时,在应用程序启动之前。