92

Rails 4 似乎SAMEORIGINX-Frame-OptionsHTTP 响应标头设置了默认值。这对安全性有好处,但它不允许您的应用程序的某些部分在iframe不同的域中可用。

您可以使用以下设置覆盖X-Frame-Options全局的值config.action_dispatch.default_headers

config.action_dispatch.default_headers['X-Frame-Options'] = "ALLOW-FROM https://apps.facebook.com"

但是你如何为单个控制器或动作覆盖它呢?

4

4 回答 4

141

如果要完全删除标题,可以创建一个after_action过滤器:

class FilesController < ApplicationController
  after_action :allow_iframe, only: :embed

  def embed
  end

private

  def allow_iframe
    response.headers.except! 'X-Frame-Options'
  end
end

或者,当然,您可以编写代码after_action以将值设置为不同的值:

class FacebookController < ApplicationController
  after_action :allow_facebook_iframe

private

  def allow_facebook_iframe
    response.headers['X-Frame-Options'] = 'ALLOW-FROM https://apps.facebook.com'
  end
end

请注意,您需要在调试时清除某些浏览器(我的 Chrome)中的缓存。

于 2013-08-26T13:50:49.220 回答
17

我只是想在此处为任何发现此链接的人提供一个更新的答案,这些人在试图弄清楚如何允许您的 Rails 应用程序嵌入 I-Frame 并遇到问题时。

截至 2020 年 5 月 28 日撰写本文时,X-Frame-Options 更改可能不是您解决问题的最佳方法。“ALLOW-FROM”选项已被所有主要浏览器完全禁止。

现代解决方案是实施 Content-Security-Policy 并设置“frame_ancestors”策略。'frame_ancestors' 键指定哪些域可以将您的应用程序嵌入为 iframe。它目前受主要浏览器支持并覆盖您的 X-Frame-Options。这将允许您防止 Clickjacking(X-Frame-Options 最初旨在帮助它在很大程度上被弃用)并在现代环境中锁定您的应用程序。

您可以在初始化程序(下面的示例)中使用 Rails 5.2 设置 Content-Security-Policy,对于 Rails < 5.2,您可以使用像 Secure Headers gem 这样的 gem:https ://github.com/github/secure_headers

如果您愿意,您还可以基于控制器/操作覆盖策略规范。

内容安全策略非常适合高级安全保护。查看您可以在 Rails 文档中配置的所有内容:https ://edgeguides.rubyonrails.org/security.html

内容安全策略的 Rails 5.2 示例:

# config/initializers/content_security_policy.rb    
    Rails.application.config.content_security_policy do |policy|
      policy.frame_ancestors :self, 'some_website_that_embeds_your_app.com'
    end

控制器特定更改策略的示例:

# Override policy inline
class PostsController < ApplicationController
  content_security_policy do |p|
    p.frame_ancestors :self, 'some_other_website_that_can_embed_posts.com'
  end
end
于 2020-05-28T23:01:50.050 回答
3

上面的答案确实帮助了我,但在 2021 年使用 Rails 4.2 应用程序时,我需要关闭 X-Frame-Options 并仅为几个 URL 指定 Content-Security-Policy。

具体来说,我使用 2checkout 作为支付提供商,他们在 iframe 中打开了一些 URL ....

我就是这样做的

class HomeController < ApplicationController
    after_action :allow_2checkout_iframe, only: [:privacy, :terms_of_service]

    def privacy
    end

    def terms_of_service
    end

    private
        def allow_2checkout_iframe
            response.headers.except! 'X-Frame-Options'
            response.headers['Content-Security-Policy'] = "frame-ancestors 'self' https://secure.2checkout.com"
        end
end
于 2021-06-04T13:49:51.327 回答
-1

对于 Rails 5+,请response.set_header('X-Frame-Options', 'ALLOW-FROM https://apps.facebook.com')改用。或者如果ALLOW-FROM不起作用并且您需要快速修复,您可以将其设置为ALLOWALL

于 2020-08-04T17:08:58.347 回答