Credenziali del cookie CORS da WebView mobile caricate localmente con file: //

Abbi pazienza, questo ha bisogno di un po ‘di spiegazioni.

Sto collaborando alla creazione di un’app ibrida per Web mobile. Il codebase principale è HTML5 e JavaScript, che verrà inserito in una visualizzazione Web mobile nativa (a la Phonegap).

Parte della funzionalità richiede che l’app invii informazioni a un servizio web controllato da uno dei nostri clienti. C’è molto poco spazio per cambiare questo servizio web in quanto viene utilizzato da altri. Inviamo JSON utilizzando un POST HTTP e riceviamo le risposte dal server. Parte di questa risposta è un cookie JSESSIONID che gestisce la nostra sessione con il server. Dopo la chiamata initSession() iniziale, è necessario inviare il cookie JSESSIONID con ogni richiesta (AJAX).

Quando viene distribuito su un dispositivo mobile, l’app Web viene avvolta nella visualizzazione Web nativa, che avvia l’applicazione Web sfogliando il file:///path/to/app/index.html .

La prima cosa che abbiamo provato è stata chiedere al nostro client di impostare Access-Control-Allow-Origin: * nell’intestazione della risposta per consentire a CORS. Abbiamo quindi provato a postare sul server:

 $.ajax({ url: 'http://thirdparty.com/ws', data: data, type: "POST", dataType: "JSON", success: successCallback, error: failedCallback }); 

Monitorando le richieste, era evidente che i cookie non venivano inclusi. Ad un’ispezione più ravvicinata c’è una sezione speciale nelle specifiche CORS per trattare le credenziali dell’utente , che include i cookie di sessione. Così ho modificato la chiamata AJAX per includere questo:

 $.ajax({ url: 'http://thirdparty.com/ws', data: data, type: "POST", dataType: "JSON", success: successCallback, error: failedCallback, xhrFields { withCredentials: true } }); 

Un altro errore, questa volta dal browser. Più lettura ha prodotto quanto segue:

Se il server di terze parti non ha risposto con un Access-Control-Allow-Credentials: true header la risposta verrebbe ignorata e non resa disponibile per il contenuto web.

Nota importante: quando si risponde a una richiesta con credenziali, il server deve specificare un dominio nell’intestazione Access-Control-Allow-Origin e non può utilizzare la wild card.

Quindi abbiamo bisogno di cambiare le intestazioni del server per includere Access-Control-Allow-Credentials: true e Access-Control-Allow-Origin per la nostra origine.

Ecco finalmente il mio problema: quando si carica una pagina Web utilizzando il protocollo file: // , l’intestazione della richiesta Origin inviata dalla vista Web è impostata su null . Pertanto non può essere analizzato dal server e quindi il server non può impostarlo in Access-Control-Allow-Origin . Ma se il server non può impostare Access-Control-Allow-Origin su un valore diverso da * non possiamo inviare credenziali, inclusi i cookie.

Quindi sono bloccato. Cosa fare? Ho visto una domanda simile pubblicata qui, ma non capisco davvero la risposta proposta. Qualsiasi aiuto sarebbe molto apprezzato!

Mi rendo conto che questa domanda è vecchia, ma ho pensato di buttarcela comunque. Nel caso di richieste CORS, il browser li prefligherà. Ciò significa che, nonostante il metodo $.ajax() che si sta utilizzando, una richiesta OPTIONS viene inviata al server.

Ciò che questa richiesta OPTIONS preflight sta effettivamente facendo è dire:

“Ehilà, foreign-server-from-some-other-domain, voglio inviarti una richiesta non semplice (i req semplici non sono preflight). La mia richiesta non-semplice prevede di avere questo tipo di intestazioni e tipo di contenuto e così via. Puoi dirmi se va bene? ”

Quindi il server farà tutto ciò che fa (probabilmente controlla qualche configurazione o database) e risponderà con l’origine (i) consentita (i), l’intestazione (i) ammissibile (i) e / oi metodi consentiti (s).

Infine, se la richiesta OPTIONS preflight ha ricevuto una risposta che consente l’effettivo metodo $.ajax() , va.

CORS non è lo stesso di JSONP.

Detto ciò, mentre withCredentials il successo preflight di withCredentials necessario che la risposta withCredentials Access-Control-Allow-Credentials (come indicato nella domanda), ovvero IN AGGIUNTA a Access-Control-Allow-Origins AND Access-Control-Allow-Methods valori, che devono includere gli aspetti della richiesta desiderata.

Per esempio – se stai facendo una richiesta CORS POST dall’origine http://foo-domain.com con intestazioni somevalue a http://bar-domain.com , una richiesta OPTIONS preflight uscirà e in ordine per il post effettivo richiesta per essere effettuata su http://bar-domain.com , la richiesta OPTIONS dovrebbe ricevere una risposta con un valore Access-Control-Allow-Origins che includesse http://foo-domain.com . Questo potrebbe essere il nome di origine stesso o * . La risposta dovrebbe anche avere un valore Access-Control-Allow-Methods che includa POST . Questo potrebbe anche essere * . Infine, se vogliamo che la nostra intestazione di somevalue sia consentita, la risposta deve contenere un valore Access-Control-Allow-Headers che includa la nostra chiave di intestazione di somevalue o * .

Per tornare indietro: se non riesci a controllare il server o non hai modo di consentire al server di consentire le tue richieste CORS, puoi sempre utilizzare JSONP o alcuni tipi di dati urlEncoded e / o effettuare semplici richieste senza intestazioni personalizzate. GET , HEAD e POST richieste POST complete sono in genere richieste semplici.

Immagino che se stai creando un’applicazione ibrida stai usando cordova. Se questo è il caso in cui non hai bisogno di CORS hai solo bisogno di elencare in bianco i domini a cui accederai.

http://docs.phonegap.com/en/3.0.0/guide_appdev_whitelist_index.md.html

Il mio suggerimento è impostare ACCESS-CONTROL-ALLOW-ORIGIN su null sul lato server

Sì, questa domanda mi disturba un po ‘.

Per quanto riguarda le specifiche CORS , null può soddisfare la situazione in cui una richiesta CORS da un file:// schema

E una raccomandazione pratica su quella specifica è impostarla come origine-lista-o-nulla , che è o una lista di origini separate dallo spazio o semplicemente “null” (a proposito, la stringa %x6E %x75 %x6C %x6C dalla definizione per origin-list-or-null è letteralmente null esadecimale)

Infine chiederai, non sarà uguale a * se impostiamo ACCESS-CONTROL-ALLOW-ORIGIN su null poiché ogni richiesta dal file:// schema file:// è valida (il che significa che ogni app ibrida può accedere al tuo endpoint se sa del tuo uri) ?

Bene, dato Access-Control-Allow-Credentials: true , credo che tu abbia un intero meccanismo di autenticazione che funziona sul server. Dovrebbe aver filtrato quelle richieste senza l’autenticazione corretta

Spero che ti sarà d’aiuto

Prova a guardare http://www.5app.co.uk. Evita l’uso delle chiamate XHR e funziona in modo affidabile sui dispositivi mobili quando le connessioni dati vanno e vengono. Il gateway quindi si interfaccia con il cliente.

Usa la richiesta JSONP. La richiesta JSONP ti consente di effettuare una richiesta di dominio incrociato. Ecco un esempio.

Ad esempio, sul lato php è necessario impostare questo:

 header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer'); header('Access-Control-Allow-Credentials: true'); // header('Cookie: PHPSESSID='.$_COOKIE['PHPSESSID']);