2013-05-21 11 views
6

Devo solo supportare new browsers.È possibile effettuare una richiesta JSONP sicura?

Devo fare affidamento su un servizio esterno per fornire dati JSONP, non possiedo quel servizio e non consente CORS.

Mi sento molto a disagio dovermi affidare alle richieste JSONP dal server esterno, poiché possono eseguire codice arbitrario sul mio terminale, che consentirebbe loro di rintracciare i miei utenti e persino di rubare le loro informazioni.

Mi chiedevo se c'era un modo per creare una richiesta JSONP che fosse anche sicura?

(correlato: How to reliably secure public JSONP requests? ma non con il nuovo rilassamento browser)

NOTA: Ho chiesto/risposto it Q & Uno stile, ma io sono molto aperto ad altre idee.

risposta

11

Sì!

È possibile. Un modo per farlo sarebbe quello di utilizzare WebWorkers. Il codice in esecuzione in WebWorkers non ha accesso al DOM o altro codice JavaScript della tua pagina.

È possibile creare un WebWorker ed eseguire la richiesta JSONP con esso, quindi terminarlo quando hai finito.

Il processo è qualcosa di simile:

  • Creare un WebWorker da un blob con l'URL per richiedere

  • Usa importScripts per caricare la richiesta JSONP con un callback locale

  • Quando viene eseguita la richiamata, inviare un messaggio allo script, che a sua volta eseguirà l'effettivo messaggio di richiamata con i dati.

In questo modo, un utente malintenzionato non avrebbe informazioni sul DOM.

Ecco un sample implementation:

// Creates a secure JSONP request using web workers. 
// url - the url to send the request to 
// data - the url parameters to send via querystring 
// callback - a function to execute when done 
function jsonp(url, data, callback) { 
    //support two parameters 
    if (typeof callback === "undefined") { 
     callback = data; 
     data = {}; 
    } 
    var getParams = ""; // serialize the GET parameters 
    for (var i in data) { 
     getParams += "&" + i + "=" + data[i]; 
    } 
    //Create a new web worker, the worker posts a message back when the JSONP is done 
    var blob = new Blob([ 
     "var cb=function(val){postMessage(val)};" + 
     "importScripts('" + url + "?callback=cb" + getParams + "');"],{ type: "text/javascript" }); 
    var blobURL = window.URL.createObjectURL(blob); 
    var worker = new Worker(blobURL); 

    // When you get a message, execute the callback and stop the WebWorker 
    worker.onmessage = function (e) { 
     callback(e.data); 
     worker.terminate(); 
     }; 
    worker.postMessage(getParams); // Send the request 
    setTimeout(function(){ 
     worker.terminate();//terminate after 10 seconds in any case. 
    },10000); 
}; 

Ecco utilizzo di esempio che funziona in JSFiddle:

jsonp("http://jsfiddle.net/echo/jsonp", { 
    "hello": "world" 
}, function (response) { 
    alert(response.hello); 
}); 

Questa implementazione non tratta con alcune altre questioni, ma impedisce tutto l'accesso al DOM o JavaScript corrente sulla pagina, uno può creare un safe WebWorker environment.

Questo dovrebbe funzionare su IE10 +, Chrome, Firefox e Safari così come i browser mobili.

Problemi correlati