In our application we have some elements that work with ajax.
We offer users to embed parts of the app in an iframe.
Everything work fine in Chrome and Mozilla. In Safari we get 422 error, and the server log looks like this:
2015-07-15T08:26:06.818885+00:00 app[web.1]: Completed 422 Unprocessable Entity in 4ms
2015-07-15T08:26:06.815411+00:00 app[web.1]: Can't verify CSRF token authenticity
2015-07-15T08:26:06.823389+00:00 app[web.1]: ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
Finally I figured out that Safari does not allow keeping cookies in iframe.
The solution I found is this:
session[:safari_cookie_fixed]exist. If not, render a code that will communicate using
postMessagewith the parent window and let him know that we need a redirection.
postMessageto the iframe when the iframe is loaded. The listener, which was rendered in case the cookie does not exist, send a signal to the parent to perform redirect, and the parent does a redirection to
/set-cookiepage in the iframe domain, adding its current url as a query-string parameter.
set_cookieaction save a cookie
safari_cookie_fixedand redirect back to the parent page (which its url is available in the query-string)
Of-course this solution requires adding some js code in the parent page, but when you give your user the iframe html code you can include the js as well.