Отключить CSRF SiteWide

Есть ли способ отключить CSRF для всех контроллеров, или он должен быть отключен для каждого контроллера? Я использую 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 ответ

Решение

Как и во многих вещах в 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, вам может потребоваться обычная страница "регистрации" с отправкой формы или область администратора с возможностью редактирования и обновления.

Я обнаружил, что можно отключить защиту CSRF, если указан ключ API. Например:

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

Это означает, что вы все еще можете принимать традиционные вызовы API в форме кодировки или XML. Если вместо этого ваш API-ключ предоставляется через заголовки, как требуют некоторые, вы можете адаптировать его для проверки request соответственно.

Другие вопросы по тегам