MobileSafari ne renverra pas les cookies avec CORS

J'ai une page de chargement dans MobileSafari qui a communiqué avec un autre serveur via CORS.

Dans les navigateurs de bureau (testé Chrome et Safari), je peux me connecter, obtenir un cookie de session et demander que le cookie de session soit renvoyé pour les demandes ultérieures afin que je puisse être authentifié avec tous les appels d'API.

Cependant, lorsque je me connecte via Mobile Safari, le cookie n'est pas renvoyé aux demandes ultérieures.

J'utilise Charles Proxy pour espionner ce qui se passe, et cela me dit:

  1. POST https://myremoteserver.com/sessions.json transmet mes informations de connexion
  2. Il réussit et la réponse est reçue avec un en Set-Cookie tête Set-Cookie valide.
  3. GET https://myremoteserver.com/checkout.json est demandé, sans un en-tête de requête Cookie .
  4. Le serveur répond comme si je ne suis pas connecté.

J'utilise cet extrait avec Zepto.js pour vous assurer que withCredentials: true est correctement configuré sur l'objet XHR. (Pardonnez le 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 

Et cet extrait fonctionne bien dans les navigateurs de bureau, et avant de l'ajouter, je n'ai pas pu conserver les cookies de session dans ces navigateurs de bureau.

Y a-t-il une certaine qualité dans MobileSafari qui empêche que cela fonctionne comme des navigateurs de bureau? Pourquoi ne fonctionne-t-il pas de la même manière?


Modifier!

Voici mon encadrement CORS mis en place dans mon profil 2.3 applications, assez standard, je crois

 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 

Aussi aujourd'hui Desktop Safari sur Mountain Lion a commencé à ne pas envoyer le cookie, se comporter comme MobileSafari. Je ne suis pas tout à fait sûr de savoir si mon évaluation hier était inexacte, ou peut-être que Apple me traque …

Est-ce que cela pourrait être affecté en utilisant https:// à l'url à distance?

Je ne sais pas si cette solution fonctionnera ou vous sera acceptable, mais j'ai eu le même problème avec Safari mobile et une application JSONP. Il semblait que Safari n'était pas configuré pour accepter les cookies de tiers. Je suis allé à Paramètres> Safari> Accepter les cookies et définir «Toujours» et le problème s'est évaporé. Bonne chance.

Puis-je configurer les cookies dans une réponse à partir d'une requête jsonp?

Vous n'avez pas mentionné si le serveur distant est sous un domaine différent ou simplement un sous-domaine différent. Je suppose que c'est dans un domaine différent.

Comme @schellsan l'a souligné, vous ne pouvez pas définir / écrire des cookies dans un domaine différent, même si la politique CORS l'autorise en raison de la restriction des cookies tiers sur le safari. C'est la dernière restriction de safari. Je pense que Firefox est sur le point de faire de même.

Solutions de contournement J'évalue actuellement:

  • Utilisez une redirection sur le serveur distant afin que, lorsque le client est redirigé (l'URL de la télécommande se trouve dans la barre du navigateur), vous pouvez configurer le cookie
  • Utilisez un en-tête personnalisé

J'étais confronté au même problème.

Ma configuration était:

  • L'application AngularJS (Ionic) sur le serveur A avec le domaine a.com
  • NodeJS avec Passport JS comme Backend sur le serveur B avec le domaine b.com

La connexion avec le cookie s'est bien déroulée sur tous les navigateurs, à l'exception de Mobile Safari sur iOS. En outre, la modification des paramètres de cookie mobile (Ne pas suivre) dans iOS n'a eu aucun impact sur le problème.

La solution était de définir un enregistrement CNAME DNS

backend.a.com CNAME b.com

Ouvrez une adresse qui définit le cookie via un iFrame – cela définira le cookie.