禁用CSRF SiteWide

时间:2014-10-15 17:13:09

标签: ruby-on-rails ruby csrf

有没有办法为所有控制器禁用CSRF,还是必须在每个控制器的基础上禁用它?我在rails上使用ruby作为API而且不需要任何类型的CSRF,因为请求不在基于会话的任何地方。我只想禁用JSON请求。

我相信这可行,但我不确定

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery
  skip_before_action :verify_authenticity_token, if: :json_request?

#Checks format for json
protected
  def json_request?
    request.format.json?
  end

end

1 个答案:

答案 0 :(得分:6)

与Rails中的许多内容一样,在基本控制器中禁用某些内容会导致在从它派生的所有内容中禁用它。要完全关闭CSRF,请在ApplicationController中禁用它:

skip_before_action :verify_authenticity_token

skip_before_action方法确实有自定义应用方式的选项,因此您可以缩小对此的关注:

skip_before_action :verify_authenticity_token, unless: csrf_required?

如您所示,您可以定义限制它的方法。如果该方法返回true,则操作将照常执行,否则将跳过。

编写API时,通常会将API :: BaseController作为中间控制器,这样您就可以将基于会话的活动与基于API的活动分开。例如:

class API::BaseController < ApplicationController
  skip_before_action :verify_authenticity_token
end

然后从该控制器派生所有特定于API的控制器。即使在主要由API驱动的应用程序中,您也可能需要一个带有表单提交的传统“注册”页面,或者一个能够编辑和更新内容的管理区域。

我发现的一个选项是在提供API密钥时禁用CSRF保护。例如:

def csrf_required?
  params[:api_key].blank?
end

这意味着您仍然可以接受传统的“表单编码”或XML API调用。如果您的API密钥是通过标头提供的,而不是某些需要,您可以根据request对其进行相应的测试。