Rails 4似乎为SAMEORIGIN
HTTP响应标头设置了默认值X-Frame-Options
。为了安全起见,这是[[great,但不允许您的应用程序的某些部分在其他域的iframe
中可用。
X-Frame-Options
设置全局覆盖config.action_dispatch.default_headers
的值:config.action_dispatch.default_headers['X-Frame-Options'] = "ALLOW-FROM https://apps.facebook.com"
但是您如何仅针对单个控制器或操作覆盖它?
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)中清除缓存。
截至撰写本文时,2020年5月28日,X-Frame-Options的更改可能不是解决问题的最佳方法。所有主要浏览器都完全不允许使用“ ALLOW-FROM”选项。
现代解决方案是实施内容安全策略并设置'frame_ancestors'策略。 'frame_ancestors'键指定哪些域可以将您的应用嵌入为iframe。目前主要浏览器都支持它,并且会覆盖您的X-Frame-Options。这将使您能够防止Clickjacking(X-Frame-Options最初旨在在不推荐使用此功能之前就提供帮助)并在现代环境中锁定您的应用程序。
您可以在初始化程序中使用Rails 5.2设置内容安全策略(以下示例),对于Rails <5.2,您可以使用像Secure Headers gem这样的gem:https://github.com/github/secure_headers
如果需要,您还可以根据控制器/操作来覆盖策略规范。
Content-Security-Policies非常适合高级安全保护。检查一下您可以在Rails文档中配置的所有内容:https://edgeguides.rubyonrails.org/security.html
[Content-Security-Policy的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