jeudi 12 septembre 2013

Dart JSONP


Ou comment contourner CORS
#dartlang #jsonp

Pour faire une requête XmlHttpRequest (HttpRequest en Dart) sur un autre domaine, on est souvent confronté à une restriction de sécurité dénommé CORS, Cross-origin resource sharing. Elle a pour but d’éviter de charger des données d’un serveur autre que celui hébergeant l’application qui n’a pas les bonnes permissions. Cette fonctionnalité est supportée par la majorité des navigateurs modernes, cependant, la plupart des serveurs ne définissent pas les entêtes nécessaires pour le bon fonctionnement de ces requêtes. Du coup, la communauté javascript a inventé un système de contournement : JSONP.

Le principe de JSONP est de charger l’url via une balise script ajouter dynamiquement. Il n’y a plus les mêmes vérifications sur des domaines différents, c’est ouvert.
  <script type="application/javascript" src="http://server2.example.com/Users/1234"></script>
Mais comment savoir quand la requête est terminé et surtout comment récupérer les données ?
C’est la magie de la méthode sioux, on va indiquer un callback à appeler et le serveur va générer le javascript qui va bien pour appeler cette méthode :
  <script type="application/javascript" src="http://server2.example.com/Users/1234?jsonp=*parseResponse*"></script>
Et le serveur retourne par exemple :
  parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
On a donc une faille de sécurité monstrueuse si le serveur qu’on appelle n’est pas sûr : il peut exécuter n’importe quel code javascript !

C’est possible d’utiliser ce principe en Dart, grâce au package _jsonp_ et à la librairie sous-jacente, js-interop. 

L’utilisation est assez simple :
  Future<js.Proxy> result = jsonp.fetch(uri: "http://example.com/rest/object/1?callback=?");

  result.then((js.Proxy proxy) {
    print(proxy.data);

    // It is important to release the data!
    js.release(proxy);
  });

Cette technique d’ajout d’une balise script ne fonctionne pas en pure Dart. Par contre, après quelques essais j’ai réussi a chargé du code Dart sur un autre domaine grâce à la méthode spawnUri. Les serveurs n’ont plus qu’à s’adapter pour générer du Dart !

Aucun commentaire:

Enregistrer un commentaire