Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MobileSafari won't send back Cookies set with CORS

I have a page loading up in MobileSafari which communicated with another server via CORS.

In desktop browsers (tested Chrome and Safari), I am able to log in, get a session cookie, and have that session cookie be sent back for subsequent requests so that I may be authenticated with all API calls.

However, when I login via Mobile Safari, the cookie does not get sent back on subsequent requests.

I'm using Charles Proxy to spy on what's going on, and it tells me:

  1. POST https://myremoteserver.com/sessions.json passes up my login info
  2. It succeeds and response is received with a valid Set-Cookie header.
  3. GET https://myremoteserver.com/checkout.json is requested, without a Cookie request header.
  4. Server responds as if I am not logged in.

I'm using this snippet with Zepto.js to ensure that the withCredentials: true is properly setup on the XHR object. (pardon the coffeescript)

# Add withCredentials:true to the xhr object to send the remote server our cookies.
xhrFactory = $.ajaxSettings.xhr
$.ajaxSettings.xhr = ->
  xhr = xhrFactory.apply(this, arguments)
  xhr.withCredentials = yes
  xhr

And that snippet works great in desktop browsers, and before I added it I was not able to preserve the session cookies in those desktop browsers.

Is there some quirk in MobileSafari that prevents this from working like desktop browsers? Why does it not work in the same way?


Edit!

here is my CORS headers setup in my rails 2.3 app, fairly standard stuff I believe

def add_cors_headers
  if valid_cors_domain
    headers['Access-Control-Allow-Origin']      = request.headers['HTTP_ORIGIN']
    headers['Access-Control-Expose-Headers']    = 'ETag'
    headers['Access-Control-Allow-Methods']     = 'GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD'
    headers['Access-Control-Allow-Headers']     = '*,x-requested-with,Content-Type,If-Modified-Since,If-None-Match'
    headers['Access-Control-Allow-Credentials'] = 'true'
    headers['Access-Control-Max-Age']           = '86400'
  end
end

Also today desktop Safari on Mountain Lion started not to send the cookie, behaving just like MobileSafari. I'm not entirely sure if my assessment yesterday was inaccurate, or perhaps Apple is just trolling me...

Also could this be affected by using https:// at the remote url?

like image 623
Alex Wayne Avatar asked Jan 08 '13 00:01

Alex Wayne


2 Answers

I don't know if this solution will work or is acceptable to you but I had the same problem with mobile Safari and a JSONP app. It seemed that Safari was not set to accept third party cookies. I went to Settings > Safari > Accept Cookies and set 'Always' and the problem evaporated. Good luck.

Can I set cookies in a response from a jsonp request?

like image 100
schellsan Avatar answered Oct 20 '22 03:10

schellsan


I believe you are experiencing what I have been seeing in my app. My issue, was caused because iOS Safari, comes with a default option "Prevent Cross-Site Tracking" enabled by default that is causing the browser to block ALL third party cookies, even cookies that are issued by your back-end server from a different domain and CORS is configured correctly.

The only solution to this problem I found was to use a proxy in production like I did in dev. I accomplished this in Azure with Azure Functions and making all request go through a proxy. At that point iOS Safari did not block my cookies everything was set as expected.

I wrote about it in my blog https://medium.com/@omikolaj1/complete-guide-to-deploying-angular-and-asp-net-33a0976d0ec1

like image 38
O.MeeKoh Avatar answered Oct 20 '22 02:10

O.MeeKoh