2013-03-01 13 views
5

Supponiamo di controllare due domini, www.api_domain.com e www.website_domain.com. www.api_domain.com offre un'API che richiede all'utente di autenticarsi e quindi utilizza un cookie di sessione per riconoscere l'utente che sta effettuando richieste. www.website_domain.com carica uno script nelle sue pagine da www.api_domain.com e tale script desidera effettuare chiamate agli URL dell'API su www.api_domain.com con il cookie dell'utente corrente e utilizzare i risultati in qualche modo nella pagina da www.website_domain.com.Cookie interdominio in IE 8 e 9 senza iframe?

Per inizialmente caricamento dello script, o per le URL API che non richiedono cookie di sessione dell'utente al lavoro, la soluzione più semplice è semplicemente quello di utilizzare un'intestazione

Access-Control-Allow-Origin: http://www.website_domain.com 

sulla risposta da www.api_domain.com. Questo sembra funzionare fuori dalla scatola su tutti i browser oltre a IE, e sebbene IE non rispetti l'intestazione Allow-Origin sulle richieste AJAX fatte usando i metodi AJAX di jQuery, ci sono librerie come xdr.js che fanno un po 'di magia dietro le quinte per make jQuery, IE e l'intestazione Allow-Origin funzionano bene insieme e si comportano come in tutti gli altri browser (non conosco i dettagli di cosa fa xdr.js, ma funziona perfettamente per le richieste non credenziali, per quanto posso vedere).

Il problema si presenta quando voglio colpire un URL su http://www.api_domain.com che richiede il cookie di sessione dell'utente. Quando questo problema è discusso in un ambiente browser agnostico, di solito sono proposte due soluzioni:

  1. Usa Access-Control-Allow-Credentials: true sulla risposta da fare i biscotti essere inviati anche con le richieste cross-domain.
  2. Creare un iframe sulla pagina su http://www.website_domain.com di origine http://www.api_domain.com, avere le due finestre comunicano tra loro utilizzando HTML5 post messages e delegare tutto responsabilità di richieste di http://www.api_domain.com al l'iframe.

sarei molto preferisce utilizzare l'opzione 1, se possibile, dal momento che consente di scrivere il codice Javascript per utilizzare l'API sul http://www.api_domain.com nello stesso modo in cui si scrive a toccare un'API dello stesso dominio. Per utilizzare l'approccio iframe, avremmo bisogno di imparare o creare un framework per inviare richieste di tipo AJAX all'iframe, con successo e gestori di errori. Significa anche che abbiamo bisogno di creare il codice da caricare nell'iframe, che sarà solo un intero gruppo di involucri sottili per colpire gli URL dell'API. Sembra solo più brutto, complicato e più difficile da capire rispetto al primo approccio.

Tuttavia, non riesco a capire come far funzionare l'opzione 1 su IE. Sto impostando Access-Control-Allow-Credentials: true sui miei URL API e tutti gli altri browser inviano cookie a tali URL, ma IE 9 non lo fa, anche con la libreria xdr.js. (Non ho testato su IE 8.) Non ci sono altri sintomi da segnalare. Posso vedere le intestazioni corrette Access-Control-Allow-Origin e Access-Control-Allow-Credentials nelle risposte da www.api_domain.com quando le visualizzo negli strumenti di sviluppo di IE, ma non ci sono intestazioni di cookie nella richiesta.

C'è qualche incantesimo o incantesimo magico che posso utilizzare per fare in modo che Internet Explorer rispetti l'intestazione Access-Control-Allow-Credentials o qualche altra intestazione che posso utilizzare riconosciuta da IE?

+1

L'impostazione della politica sulla privacy di p3p è d'aiuto? http://stackoverflow.com/questions/2666376/copying-cookies-cross-domain-why-is-ie-blocking-cookies-other-browsers-are-send?rq=1 – flup

+0

@flup No, è del tutto irrilevante Questo. –

+0

Come una parte che non aiuta a rispondere a questa domanda ma è probabile che sia utile a chiunque la legga: piuttosto che creare il proprio iframe proxy, considerando l'utilizzo di [questa libreria] (https://github.com/jpillora/xdomain/) . Non l'ho provato, ma sembra che dovrebbe fare in modo trasparente tutto il lavoro di proxy del traffico AJAX tra domini tramite messaggio postale per voi. A meno che non sia inoltre necessario il supporto di supercookie per gestire il numero crescente di browser che bloccano i cookie di "terze parti" per impostazione predefinita (compresi quelli impostati negli iframe), dovrebbe essere adeguato. –

risposta

9

L'opzione 1 non è possibile in IE9 o inferiore perché non c'è supporto per CORS che utilizza XMLHttpRequest. Inoltre, se si tenta di utilizzare XDomainRequest, non sarà mai possibile inviare cookie insieme alla richiesta. Sono stato in questa strada più volte lavorando sulla scrittura di una libreria di test ui da utilizzare con testswarm. Quello che vuoi fare non è possibile in questo modo.

Ecco un post di Eric legge, uno sviluppatore ex-Microsoft, discutere la questione in dettaglio: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

Le sezioni pertinenti, che rendono chiaro che l'invio di biscotti con una richiesta CORS è impossibile in IE 8 e 9, sono i seguenti:

In Internet Explorer 8, è stato introdotto l'oggetto XDomainRequest. Questo oggetto consente alle applicazioni AJAX di creare richieste di origine incrociata sicure assicurando che le risposte HTTP possano essere lette solo dalla pagina corrente se l'origine dati indica che la risposta è pubblica; in tal modo, la garanzia di sicurezza della stessa politica di origine è protetta. Le risposte indicano la loro volontà di consentire l'accesso tra domini includendo l'intestazione di risposta HTTP Access-Control-Allow-Origin con valore * o l'origine esatta della pagina chiamante.

Durante la progettazione del nuovo oggetto, la garanzia che i siti e i servizi esistenti non sarebbero stati messi a rischio era la nostra massima priorità. A tal fine, abbiamo imposto una serie di restrizioni sul tipo di richieste che possono essere fatte con l'oggetto XDomainRequest.

...

5: nessuna autenticazione o cookie sarà inviato con la richiesta

Al fine di evitare abusi di autorità ambiente dell'utente (ad esempio, i cookie, le credenziali HTTP, i certificati client, ecc), la richiesta verrà rimossa dai cookie e dalle credenziali e ignorerà qualsiasi sfida di autenticazione o direttive Set-Cookie nella risposta HTTP. XDomainRequests non verrà inviato su connessioni autenticate in precedenza, poiché alcuni protocolli di autenticazione di Windows (ad esempio NTLM/Kerberos) sono basati sulla connessione anziché su richiesta.

I siti che desiderano eseguire l'autenticazione dell'utente per richieste di origine incrociata possono utilizzare metodi espliciti (ad esempio token nel corpo POST o URL) per passare queste informazioni di autenticazione senza rischiare l'autorizzazione dell'ambiente dell'utente.

Ora supponendo di controllare entrambe le posizioni, si potrebbe presumibilmente creare un server di processo di autenticazione del server e andate circa il superamento di un id di sessione di sorta forniti dal dominio, per l'altro dominio, di cui il cliente è in realtà attraverso la tua richiesta. Non è carino, ma funziona. Questo metodo è anche menzionato nell'articolo. Dovrai fare attenzione però perché apre la possibilità per il dirottamento di sessione.

+0

Link impressionante, grazie. Rende chiaro che questo non è possibile. L'autenticazione da server a server sembra una soluzione ancora più clamorosa dell'uso di un iframe, quindi per ora rimarrò con la soluzione iframe. –

0

IE8 + ha un'alternativa a XMLHttpRequest che supporta le credenziali che è XDomainRequest.comunque, XDomainRequest non è implementato da JQuery perché ha meno funzionalità di quelle fornite da XMLHttpRequest, ma c'è un plugin come jQuery CORS Plugin che fornisce quello che ti serve.

plugin jQuery che aggiunge in modo trasparente Croce Origin Resource Sharing (CORS) tra i browser, tra cui IE8 +, per consentire cross-domain Ajax richieste con i biscotti e le intestazioni di supporto.

anche io penso ma non sono sicuro che IE non supporta i caratteri jolly nelle intestazioni come Access-Control-Allow-Origin: *.

+0

Non stiamo usando i caratteri jolly; non è possibile utilizzare i caratteri jolly con le richieste credenziali in tutti i browser che ho visto in ogni caso, secondo le specifiche CORS. Il repository github che hai collegato sembra promettente, ma sono un po 'confuso. C'è sia Java e Javascript lì, e nessuna istruzione di utilizzo; è l'idea che il Javascript funziona solo in combinazione con la roba Java utilizzata in qualche modo per gestire le richieste? –

+0

in realtà non ho ancora provato, penso che il java sia solo per test lato server. puoi controllare anche questo https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest –