Ivan
Ivan

Reputation: 135

Rails 6. Allow the specific pages be embedded in iFrame by any other domain

I'd like to allow anyone to embed my Rails website via iFrame. But I want to open only some specific routes, like /emded/entity1/:entity1_id and /emded/entity2/:entity2_id.

For example, Youtube does that. I can embed the following code:

<iframe width="420" height="315"src="https://www.youtube.com/embed/tgbNymZ7vqY">
</iframe>

But if I change the src attribute to just https://www.youtube.com/, this iframe won't display anything.

What is the way to do the same in Rails?

I've tried to follow this guide that I found for the Rails 4: http://jerodsanto.net/2013/12/rails-4-let-specific-actions-be-embedded-as-iframes/

I've created a method in Application Controller:

  def allow_iframe
    response.headers.delete "X-Frame-Options"
  end

Then I've added it to the controller with action that shows the content (page) for the iframe. after_action :allow_iframe, only: :show_page_in_iframe

And here is the controller action itself:

  def show_page_in_iframe
    ...
    
    respond_to do |format|
      format.html { render layout: 'iframe' }
    end
  end

Then I've deployed these changes to Production, embed the iframe with the corresponding URL to a 'localhost' page.

<iframe src="https://www.example.com/entity1/embed/66efdc3e-7cb7-436d-98e8-63275fa74ebd" height="500" width="100%" style="border:0"></iframe>

But in the Chrome console I can see the Refused to display 'https://www.example.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'. error message.

What did I do wrong here? Is this approach still workable for Rails 6?

Update 1. After some debugging in localhost, I've found out that the 'X-Frame-Options' value is deleted only if I have the response.headers.delete "X-Frame-Options" line precisely in the controller action. But deployment of these changes to Production (Heroku) hasn't solved the issue.

Update 2. Also, I've tried to set the ALLOWALL value for the X-Frame-Options - it hasn't helped me as well.

Update 3. Also, I've tried to delete the X-Frame-Options another way: response.headers.except! 'X-Frame-Options' - it doesn't work as well.

Upvotes: 5

Views: 3602

Answers (2)

fkoessler
fkoessler

Reputation: 7276

Configure the HTTP Content-Security-Policy response header using Rails content_security_policy helper. Use it directly in the controller(s) that you want to allow in an iframe:

class AllowInIFrameController
  content_security_policy do |f|
    f.frame_ancestors "*"
  end

  def iframe; end
end

Upvotes: 0

Vishal Jain
Vishal Jain

Reputation: 501

Have you tried setting frame_ancestors?

# config/initializers/content_security_policy.rb    
Rails.application.config.content_security_policy do |policy|
  policy.frame_ancestors :self, "*"
end

Upvotes: 2

Related Questions