Как установить заголовки HTTP для 404 не найденных страниц с Rails / Puma - PullRequest
0 голосов
/ 28 января 2020

Мне нужно установить HTTP-заголовок X-Frame-Options для страниц, которые возвращают 404 - Not Found в моем приложении rails, но я не могу понять, как это сделать. Я не могу установить эти заголовки, используя рельсы, я нашел одну возможную причину здесь . Тем не менее, я не знаю, как я могу установить их с помощью веб-сервера, я использую Puma.

На самом деле у меня нет ничего, что может быть ClickJacked на моих 404 - not found страницах, но внешняя организация по безопасности все еще требует от меня этого.

1 Ответ

0 голосов
/ 28 января 2020

В Rails исключения обрабатываются config.exceptions_app. Приложение по умолчанию просто отображает stati c html файлы из каталога publi c, но это может быть любое приложение, совместимое с стойкой.

Наиболее базовый c пример приложения, совместимого с Rack:

app = ->(env){  [ 404, { "Content-Type" => "text/plain", "X-Frame-Options" => "some value" }, ["Oh no I cant find it!"] ] }

Он принимает один аргумент (A ha sh) и возвращает массив (состояние, заголовки, тело).

Оба маршрута Rails и ActionController::Metal (и, следовательно, все ваши контроллеры) являются приложениями, совместимыми со стойками, и даже config/application.rb. На самом деле Rails - это просто русская кукольная схема приложений Rack.

Если вы хотите справиться с этим через свои маршруты, вы можете сделать:

# config/application.rb
config.exceptions_app = self.routes
# config/routes.rb
get '/404', to: "errors#not_found"
get '/422', to: "errors#unprocessable_entity"
get '/500', to: "errors#internal_error"
class ErrorsController < ActionController::Base
  before_action do
    response.set_header('X-Frame-Options', 'HEADER VALUE')
  end

  def not_found
    respond_to do |format|
      format.html { render file: Rails.root.join('public', '404.html'), layout: false, status: :not_found }
    end
  end

  def unprocessable_entity 
    respond_to do |format|
      format.html { render file: Rails.root.join('public', '422.html'), layout: false, status: :unprocessable_entity }
    end
  end

  def internal_error
    respond_to do |format|
      format.html { render file: Rails.root.join('public', '500.html'), layout: false, status: :internal_server_error }
    end
  end
end
...