PayPal Open Source Utility Suite pour l'interopérabilité entre domaines

L'auteur du document, un développeur de PayPal, décrit un ensemble d'utilitaires pour l'interaction entre domaines.



Chez PayPal, nous écrivons beaucoup de code javascript qui commence finalement à fonctionner sur d'autres sites Web et d'autres domaines. Un exemple frappant est checkout.js , un script d'intégration qui couvre entiÚrement le processus de passation et de paiement d'une commande en utilisant notre service, qui permet aux marchands d'intégrer trÚs facilement et naturellement notre bouton et le mécanisme de paiement dans leurs sites.

L'exécution de notre code sur des sites tiers comporte de nombreux risques et écueils, mais il existe certains points clés:

  • Nous ne pouvons absolument pas casser de sites. Cela signifie que nous ne modifions pas les variables globales que nous n'avons pas créées, y compris les polyfillings pour les API de navigateur. Nous ne le faisons pas, car une telle approche rend presque toujours le suivi des bogues presque impossible.
  • Mais les sites peuvent mĂȘme nous casser, ce qu'ils font assez souvent. Un exemple rĂ©cent: un site a remplacĂ© Array.prototype.toJSON ce qui a provoquĂ© le JSON.stringify de JSON.stringify . De nombreux sites Web incluent le WeakMap WeakMap, qui, contrairement Ă  sa version native, ne fonctionne pas sur les objets de fenĂȘtre interdomaines. Par consĂ©quent, sans vĂ©rifications prĂ©liminaires supplĂ©mentaires, nous ne pouvons que faire confiance Ă  notre propre code.
  • Les restrictions inter-domaines (dĂ©crivant ce que vous pouvez et ne pouvez pas faire avec un cadre Ă©lectronique ou une fenĂȘtre contextuelle contenant le contenu d'un autre domaine Ă  l'intĂ©rieur) ne sont pas claires, et les rĂšgles, en outre, changent assez souvent en fonction du navigateur dans lequel vous vous trouvez. Par exemple, dans IE et Edge, vous ne pouvez littĂ©ralement pas envoyer de message entre la fenĂȘtre contextuelle et la fenĂȘtre parent si elles ont des domaines diffĂ©rents. Cela ne peut se faire qu'en recourant Ă  des hacks humiliants.
  • Certains navigateurs donnent des choses vraiment Ă©tranges. Par exemple, la seule mĂ©thode efficace pour vĂ©rifier le domaine de la fenĂȘtre consiste Ă  try/catch pour accĂ©der ou dĂ©finir les propriĂ©tĂ©s de l'objet fenĂȘtre. Mais mĂȘme dans cet esprit, Safari insiste pour que l'erreur d'origine correspondante apparaisse dans la console pour cette action. Ce problĂšme s'est transformĂ© en gĂ©nĂ©rateur de confusion: nos marchands ont rĂ©digĂ© un rapport de bogue, et nous leur avons dit que cette erreur devait ĂȘtre ignorĂ©e.
  • Les limitations, conçues comme un moyen de lutter contre la publicitĂ© intrusive, interfĂšrent souvent avec le fonctionnement normal de notre code sur d'autres sites. Par exemple, il est possible d'ouvrir une fenĂȘtre pop-up uniquement au moment mĂȘme oĂč l'utilisateur clique sur notre bouton. Essayez de faire une sorte d'interaction asynchrone, c'est fait: le navigateur bloquera la fenĂȘtre pop-up, mĂȘme si son apparence Ă©tait formellement le rĂ©sultat de l'action de l'utilisateur. En plus de cela, les restrictions des cookies tiers conçues pour empĂȘcher la collecte d'informations publicitaires entravent presque toujours nos tentatives de suivi des sessions des utilisateurs dans les cadres Ă©lectroniques.

L'annĂ©e derniĂšre, nous avons dĂ©cidĂ© de nous concentrer sur la crĂ©ation d'un ensemble d'outils vraiment puissants pour aider Ă  Ă©viter ces Ă©cueils et crĂ©er une excellente expĂ©rience utilisateur sans avoir Ă  se soucier constamment de l'arrivĂ©e des messages et de l'affichage de toutes les fenĂȘtres.

Nous avons ouvert tout le code source de l'ensemble. Si vous souhaitez créer des interactions qui fonctionnent avec votre systÚme à partir d'autres sites ou simplement entre différents domaines au sein de votre organisation, la recherche se termine ici.

grognon


image

Tout d'abord, l'essentiel. Nous voulions créer une piÚce intelligente sur la base de laquelle tous les outils que nous avions prévus fonctionneraient. Nous avons une liste formelle de technologies que nous aimons, mais les combiner en un ensemble de qualité n'est pas une tùche facile. Nous avons décidé de simplifier notre travail à l'avenir autant que possible, et donc chaque fois que nous voulons publier une nouvelle bibliothÚque ou un outil interdomaines, nous bifurquons le grognon et commençons à coder, sans nous soucier de prédéfinir un environnement ou des outils.

→ Plus de dĂ©tails ici

post-robot


image

Le premier vrai problÚme technique que nous voulions résoudre était la messagerie entre Windows et iPhones. Vous pensez que vous pouvez simplement prendre window.postMessage et commencer à saupoudrer des messages à droite et à gauche? Détrompez-vous:

  • Il n'y a pas de rĂ©ponses ou de rappels, ce qui rend la demande de donnĂ©es Ă  partir d'une autre fenĂȘtre ou la rĂ©cupĂ©ration de donnĂ©es Ă  partir d'une rĂ©ponse une entreprise trĂšs dĂ©licate.
  • IE / Edge ne vous permet pas d'utiliser postMessage entre la fenĂȘtre contextuelle et la fenĂȘtre parent si leurs domaines sont diffĂ©rents.
  • Il n'y a presque pas de gestion des erreurs. Comme, cependant, et un moyen de dĂ©terminer qu'une autre fenĂȘtre a gĂ©nĂ©ralement reçu votre message.
  • Vous ne pouvez pas envoyer de types de donnĂ©es plus intĂ©ressants, tels que des fonctions, des promesses, des objets d'erreur et autres.

post-robot vise à résoudre tous ces problÚmes d'un seul coup, en fournissant un moyen stable et fiable d'envoyer des messages et de recevoir des réponses.

→ Plus de dĂ©tails ici

xcomponent


image

Nous aimons utiliser React, et nous aimons le grand par sa simplicitĂ©, l'idĂ©e de composants fonctionnant sur le principe «data down, actions up». Dans le mĂȘme temps, le concept React vise Ă  rendre l'interface utilisateur directement sur votre page, sans aucun cadre ni restriction interdomaines. Mais il y a un «mais» significatif: nous n'essaierions mĂȘme pas de tĂ©lĂ©charger React sur un site qui ne nous appartient pas.

Nous nous sommes demandĂ©: que se passerait-il si nous incluions des iPhones et des fenĂȘtres contextuelles dans des composants de type React auxquels nous pouvions directement transmettre des propriĂ©tĂ©s et des rappels et permettre aux fenĂȘtres enfants d'appeler directement les fonctions transmises par le parent?

Les cadres électroniques, en rÚgle générale, ne conviennent pas à cela. Autrement dit, dans des situations normales, en utilisant window.postMessage vous ne pouvez envoyer que des objets et des lignes simples vers un iframe et les sauvegarder vers son parent. Mais avec xcomponent, vous avez la possibilité de dessiner un iframe sans avoir à configurer de gestionnaire de messages: vous transférerez simplement les données et les fonctions directement à l'iframe, et il recevra directement toutes les propriétés que vous lui passerez dans l'objet window.xprops .

De plus, il ajuste automatiquement les liaisons aux frameworks populaires tels que React, Angular, Vue et autres, ce qui vous permet de dessiner les cadres dans votre application de maniĂšre native sans avoir Ă  vous soucier de la laideur des cadres.

→ Plus de dĂ©tails ici

→ Et voici comment nous utilisons xcomponent dans PayPal

xcomponent-demo


image

GuidĂ©s par les mĂȘmes considĂ©rations que dans le cas de grumbler, nous avons voulu simplifier le travail sur les composants xcomponent autant que possible afin que la configuration de l'environnement et des outils ne ralentisse pas le travail. Tout le monde aime quand vous pouvez simplement commencer Ă  coder.

Par consĂ©quent, nous avons publiĂ© xcomponent-demo - un modĂšle que vous pouvez crĂ©er et dĂ©marrer. Il a tout ce dont vous avez besoin pour crĂ©er, tester, publier et mĂȘme taper statiquement votre code et publier des x-composants pour un usage gĂ©nĂ©ral.

cross-domain-utils


image

Travailler avec des fenĂȘtres interdomaines est une chose dĂ©licate. Il y a beaucoup de questions. Par exemple, comment savoir avec certitude que la fenĂȘtre d'un autre domaine est fermĂ©e? À quoi correspond son domaine avec le vĂŽtre? Quels sont ses enfants? Les navigateurs fournissent des API simples pour certaines de ces tĂąches, mais dans chaque navigateur, tout fonctionne diffĂ©remment.

Avec les utilitaires interdomaines, nous avons essayĂ© de crĂ©er une bibliothĂšque de mĂ©thodes auxiliaires conçues pour aider Ă  travailler avec les cas courants, simplifiant le travail avec les fenĂȘtres interdomaines et Ă©liminant le besoin de se soucier constamment des erreurs ou des avertissements dans la console. L'outil, entre autres, vous permet d'Ă©viter des cas extrĂȘmes vraiment Ă©tranges, comme celui-ci:



Edge, comme toujours, dans son répertoire.

cross-domain-safe-faiblessemap


image

Le stockage d'objets de fenĂȘtre est un processus coĂ»teux en RAM, mĂȘme si la fenĂȘtre dont vous stockez la rĂ©fĂ©rence est fermĂ©e.

WeakMaps est idĂ©al pour stocker des donnĂ©es de fenĂȘtre car:

  • Ils ne stockent pas la rĂ©fĂ©rence de l'objet fenĂȘtre lorsqu'il n'est plus utilisĂ© ailleurs.
  • Il n'est pas possible de dĂ©finir directement les propriĂ©tĂ©s d'une fenĂȘtre interdomaine, par consĂ©quent, l'association des donnĂ©es avec la fenĂȘtre (par exemple, le rappel qui doit ĂȘtre appelĂ© lorsque la fenĂȘtre est fermĂ©e) est difficile. L'utilisation de WeakMap simplifie ce processus. Pour ce faire, utilisez simplement la fenĂȘtre comme une clĂ© de carte faible, puis vous pouvez stocker toutes les donnĂ©es que vous souhaitez.

Le seul problĂšme est que de nombreux joints WeakMap existants tentent d'appeler Object.defineProperty par clĂ©, ce qui conduit immĂ©diatement Ă  l'Ă©chec dans les cas oĂč la clĂ© est une fenĂȘtre Object.defineProperty avec un accĂšs limitĂ©.

En revanche, la carte faible de sĂ©curitĂ© inter-domaines est conçue pour rendre le travail avec les fenĂȘtres inter-domaines utilisant leurs clĂ©s et l'implĂ©mentation native de WeakMap (si disponible) aussi prĂ©visible et fiable que possible.

zalgo-promise


image

De nombreux navigateurs privent simplement la prioritĂ© de tout ce qui est envoyĂ© Ă  setTimeout si l'onglet du navigateur dans lequel votre code s'exĂ©cute n'est pas net. Par consĂ©quent, lorsque vous travaillez sur quelque chose qui devrait fonctionner dans une fenĂȘtre contextuelle et que vous devez envoyer un message au parent et lui demander de faire quelque chose ... Dans ce cas, n'importe quel setTimeout ralentira spĂ©cifiquement le travail du parent.

Par conséquent, la solution est simple: nous refusons setTimeout pour tout chemin d'exécution de code critique, non?

Le problĂšme est que la plupart des wrappers de promesses intermĂ©diaires existants, en l'absence d'aides comme setImmediate recours Ă  setTimeout pour garantir que la fonction transmise .then est alors appelĂ©e de maniĂšre asynchrone. Par consĂ©quent, si vous souhaitez profiter des promesses dans une variĂ©tĂ© de navigateurs et en mĂȘme temps faire exĂ©cuter le code dans les fenĂȘtres sans focus, alors vous n'avez pas de chance.

zalgo-promise essaie de résoudre ce problÚme en mettant toutes les promesses en mode synchrone par défaut. Cela signifie que si elles sont résolues de maniÚre synchrone, la fonction .then() transmise sera également appelée de maniÚre synchrone. Cela s'appelle promesse de zalgo parce que nous avons littéralement décidé de libérer le zalgo (aprÚs un examen attentif des avantages et des inconvénients).

→ Plus de dĂ©tails ici

beaver-logger


image

L'un des points importants liĂ©s Ă  l'exĂ©cution de code sur d'autres domaines est que vous devez savoir ce qui se passe et comment les gens utilisent vos produits. Et au moins, vous devez connaĂźtre les cas oĂč le code provoque des scripts erronĂ©s ou casse le site de quelqu'un.

D'un autre cÎté, il n'est pas nécessaire d'envoyer un signal aprÚs l'autre ou d'écrire dans le journal une centaine de demandes consécutives pour chaque événement pour lequel vous souhaitez enregistrer.

beaver-logger essaie de rĂ©soudre ce problĂšme en sĂ©lectionnant et en liant les journaux et en les vidant pĂ©riodiquement sur votre serveur. Il comprend mĂȘme un composant serveur du nƓud pour recevoir les journaux, mais vous pouvez l'adapter librement comme vous le souhaitez pour n'importe quelle plate-forme prĂ©fĂ©rĂ©e.

fetch-robot


image

CORS est un mal de tĂȘte. L'obtention des en-tĂȘtes corrects nĂ©cessite de configurer sur le serveur chaque point de terminaison individuel. Et si nous ne parlons pas d'une demande GET, CORS nous oblige Ă  effectuer des opĂ©rations d'Ă©change supplĂ©mentaires pour dĂ©terminer s'il est sĂ»r de faire telle ou telle demande finale.

fetch-robot est un nouveau module expĂ©rimental visant Ă  rĂ©soudre ce problĂšme. Il vous permet de publier en un seul endroit un manifeste qui dĂ©finit les URL qui peuvent ĂȘtre appelĂ©es, ainsi que qui elles peuvent ĂȘtre appelĂ©es et quels en-tĂȘtes et autres champs peuvent ĂȘtre utilisĂ©s.

Il affiche le contenu des URL avec un domaine diffĂ©rent via un iframe. En utilisant post-robot, la mĂȘme trame Ă©lectronique passe tous les messages Ă  travers elle-mĂȘme, ce qui Ă©vite le problĂšme des interactions supplĂ©mentaires (puisque toutes les vĂ©rifications sont effectuĂ©es cĂŽtĂ© client, Ă  l'intĂ©rieur de la trame de confiance).

→ Plus de dĂ©tails ici

Merci Ă  tous d'avoir lu, et si vous avez des idĂ©es sur les outils manquants dans la boĂźte Ă  outils d'interaction entre domaines ou sur ce qui peut ĂȘtre amĂ©liorĂ©, veuillez Ă©crire Ă  l'auteur!

- Daniel, équipe de développement de l'outil de paiement PayPal

image

Source: https://habr.com/ru/post/fr407657/


All Articles