Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sessions of Rails app loaded in iFrame no working

I have a Rails 6.1 app that uses sessions to store some data. When I open the app in an iFrame the sessions do not work (I cannot get their value when navigating to another page of the app, still inside the same iFrame)

I read a lot about this and played around with the cookies same_site configurations etc.

I also read about Chrome being the reason but I tried it in Safari with the same issue.

But I do not want to share sessions between the rails app and the page that contains the iFrame. I just want that the app works normally inside the iFrame.

Any ideas what could be the reason?

like image 895
almo Avatar asked Oct 23 '25 07:10

almo


1 Answers

In order for your session cookie to work inside of an iframe, you need to explicitly set its SameSite setting to None.

Rails version ≥ 6.1

Rails 6.1 introduced a new configuration option, which you can set e.g. in your config/application.rb:

config.action_dispatch.cookies_same_site_protection = :none

The relevant section on the guides is here.

Rails version < 6.1

Your best bet is most likely to use the rails_same_site_cookie gem.

Secure setting

When setting SameSite to None, you must also ensure that your cookies are sent with the Secure setting set to true. This happens when you uncomment the following line in config/environments/production.rb:

config.force_ssl = true

Where is this change from?

The relevant commit for Rails 6.1 is here. It boils down to Rails now explicitly setting SameSite=Lax on every cookie it sends.

Testing

I have found that the best way to locally test a setup such as this one is to run a separate server (e.g. a Middleman instance) to simulate the third party page which embeds your Rails app in an iframe.

Then you can point one browser tab to localhost:3000/my/iframed/page, and the other to lvh.me:4567/my/embedding/page. You should be able to sign in one tab and act as the signed in user in the other.

It is crucial to also test this in a production-like environment.

None vs Lax vs Strict

If you were to set SameSite=Lax, this setup would only work when both tabs are pointing to the same domain, e.g. localhost. With SameSite=Strict, it would not work at all.

When you are testing this, if you switch from e.g. :lax back to :none, you will be logged out from both tabs.

Response headers

Note that changing SameSite's value is not enough to set up your Rails app to work inside of an iframe. You also need to set the right headers in the relevant controller action, like so:

response.set_header("X-Frame-Options", "ALLOW-FROM #{embedding_url}")
response.set_header("Content-Security-Policy", "frame-ancestors 'self' #{embedding_url}")

Where embedding_url can be *, if you'd like anyone to be able to embed your Rails app via an iframe.

For further reading, the nice people over at makandra have compiled a card specifically about the SameSite setting.

Safari support

There is nothing you can do to fix the problem in Safari—besides asking your users to uncheck the Prevent cross-site tracking checkbox in their preferences. In the future, the same is likely to apply to all major browsers (see here for the relevant Chrome blog post).

like image 200
bumcode Avatar answered Oct 24 '25 21:10

bumcode



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!