首页 > 解决方案 > 如何使用 Rails/Puma 为 404 Not found 页面设置 HTTP 标头

问题描述

我需要为在我的 rails 应用程序X-Frame-Options中返回的页面设置 HTTP 标头,404 - Not Found但我不知道该怎么做。我无法使用 rails 设置这些标题,我在这里找到了一个可能的原因。但是,我也不知道如何使用 Web 服务器设置它们,我使用的是 Puma。

ClickJacked我的页面中实际上没有任何内容,404 - not found但外部安全组织仍然要求我这样做。

标签: ruby-on-railspumax-frame-options

解决方案


在 Rails 中,异常由config.exceptions_app. 默认应用程序仅呈现来自公共目录的静态 html 文件,但这可以是任何机架兼容的应用程序。

机架兼容应用程序的最基本示例是:

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

它接受一个参数(哈希)并返回一个数组(状态、标题、正文)。

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

推荐阅读