Ruby on rails 4 app does not work in iframe
Ruby on-RailsRuby on-Rails-3IframeRuby on-Rails-4Ruby on-Rails Problem Overview
How can I embed my rails app into another website via iframe?
It works nicely with RoR 3, but not with RoR 4:
<iframe src="http://myrailsapp.com/" width="100%" height="50" id="rails_iframe">error!</iframe>
I tried to use verify_authenticity_token
and protect_from_forgery
options in my controller... seems it's something else (but I'm not sure).
upd. Example: http://jsfiddle.net/zP329/
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
This has to do with Rails 4 enabling additional security protocols by default: http://weblog.rubyonrails.org/2013/2/25/Rails-4-0-beta1/
The setting that breaks iFrames on remote sites is X-Frame-Options. By default, this is set to SAMEORIGIN, which prevents the content from being loading cross domain:
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN'
}
You can read about the new default headers here: http://edgeguides.rubyonrails.org/security.html#default-headers
In order to allow the iFrame to work cross domain, you can change the default headers to allow X-Frame across domain.
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'ALLOWALL'
}
Solution 2 - Ruby on-Rails
Rails 4
added a default X-Frame-Options
HTTP header value of SAMEORIGIN
. This is good for security, but when you do want your action
to be called in an iframe
, you can do this:
To Allow all Origins:
class MyController < ApplicationController
def iframe_action
response.headers.delete "X-Frame-Options"
render_something
end
end
To Allow a Specific Origin:
class MyController < ApplicationController
def iframe_action
response.headers["X-FRAME-OPTIONS"] = "ALLOW-FROM http://some-origin.com"
render_something
end
end
Use :after_filter
When you need to use more than one of your action
in an iframe
, it's a good idea to make a method and call it with :after_filter
:
class ApplicationController < ActionController::Base
private
def allow_iframe
response.headers.delete "X-Frame-Options"
end
end
Use it in your controllers like this:
class MyController < ApplicationController
after_filter :allow_iframe, only: [:basic_embed, :awesome_embed]
def basic_embed
render_something
end
def awesome_embed
render_something
end
# Other Actions...
end
Solution 3 - Ruby on-Rails
Update: seems like ALLOW-FROM and ALLOWALL are currently both invalid "X-Frame-Options" header values. The only two valid ones are DENY and SAMEORIGIN and neither allows access from another origin. See MDN documentation: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options.
So looks like response.headers.delete "X-Frame-Options"
is the only way now to enable displaying content in an iframe on another site. But I'd love to be proven otherwise if anyone has any knowledge I don't.
Solution 4 - Ruby on-Rails
I'm working with Rails 6 and Chromium 76. Previous solution with X-Frame-Options is not working. But I've noticed that it works very well when we attach online iframe with JS. So, I just made this simple solution in my view:
<div id='iframe_wrapper' 'data-iframe-content'='<iframe src="https://host.com/"></iframe>'>
</div>
...and add JS code like this:
$(document).ready(function() {
var wrapper = $('#iframe_wrapper')[0]
wrapper.innerHTML = wrapper.attributes['data-iframe-content'].value
})