Ajax / Same Origin / Cors

Bonjour

J'ai lu avec intérêt le tuto de J-M-L sur les techniques avancées de serveur web sur Arduino.

Je me pose des questions sur la faisabilité d'une architecture dans laquelle j'aurais :

  • Un pc avec un navigateur web chez plusieurs personnes, avec différents niveaux d'autorisation d'accès
  • Un site web hébergé chez X (Gandi, OVH, etc.)
  • Des systèmes de prise de mesure sur des sites distants, chacun avec un module type Arduino et des capteurs et un lien Internet disponible (routeur, box...). Je peux faire en sorte de bénéficier d'une adresse IP fixe pour chacun, ou encore mettre en place un mécanisme de redirection d'adresse dynamique.

Le site web aura plusieurs pages, dont certaines sont destinées à afficher des graphiques représentant l'état et l'évolution passée des mesures. Pour cela, je pourrais utiliser la technique Ajax pour interroger directement un arduino et mettre à jour le graphique correspondant.

Le tuto sus-cité contient l'information pour réaliser techniquement ce fonctionnement. Je me pose des questions au niveau des protection "same origin" sur le serveur web et sur le navigateur. Comment faire en sorte qu'une page web à laquelle on accède par http://monDomaine.truc hébergée chez X, puisse lire de l'ajax à une adresse http://123.45.67.89/arduino2/capteur4 ?

J'ai cru comprendre qu'il existe un mécanisme nommé CORS pour que ça soit faisable, mais j'ignore tout de sa mise en oeuvre. Quelles sont les dispositions à prendre, que ce soit au niveau technique ou de la relation contractuelle avec le fournisseur d'accès ?

Salut

Le serveur ne lit jamais ce qu'il y a sur un client (navigateur), c'est toujours le navigateur qui envoie une requête avec soit de l'information à stocker, soit une demande d'information

Donc vous pouvez avoir autant de clients "capteurs" qui remontent de l'information vers OVH (par exemple) ou autant de clients "navigateurs" en consultation de l'information que vous voulez. Aucun des clients n'a besoin d'une IP fixe, il faut juste qu'ils aient accès au serveur chez OVH.

si vous voulez que le Serveur OVH puisse interroger un client de type capteur, c'est que les rôles sont inversés. OVH devient le client d'un serveur qui serait le capteur. Dans ce cas il faut que le serveur OVH puisse trouver le capteur, et donc connaisse son adresse IP ou nom de domaine (il faut qu'une route puisse être établi jusqu'au capteur)
il n'y a pas de problème de "same origin", le navigateur voit bien toutes les données provenir d'OVH.


Rien n'empêche d'être à la fois client et serveur, ça peut être le même arduino qui émet une requête ou répond à une requête. Dans un cas il est client, dans l'autre il est serveur. (il faudra éventuellement gérer des requêtes asynchrones)

Cependant la structure typique c'est de ne pas ouvrir l'accès aux capteurs mais d'avoir chaque capteur qui remonte l'information chez OVH qui fait office d'agrégateur d'information et ensuite vous avez une interface web (un autre programme serveur) qui permet d'aller consulter les informations stockées

Je suis dans le premier schéma. Chaque Arduino se comporte comme un serveur qui répond à des requêtes Ajax en renvoyant un objet JSON composé dynamiquement à partir d'une table de mesures. Par exemple il envoie les 300 dernières mesures, empaquetées dans un tableau JSON, pour qu'on puisse en faire un graphique. Aujourd'hui je teste ça avec la page web en "localhost" et un ESP32 en 192.168.1.xx sur ma box en wifi. Les navigateurs essayés (Firefox, Chrome, Edge) ne trouvent rien à redire.

Petite différence par rapport au schéma 1, je peux avoir dix capteurs différents sur le même site avec la même adresse IP, mais je peux avoir plusieurs sites distincts avec des adresses IP distinctes. Dans mon approche actuelle, il y a une requête JSON par capteur.

En fait, je suppose mais ne suis pas certain que ce soit bien la réalité, le serveur web intermédiaire ne voit pas passer ces données, tout comme si c'était une image située sur un site externe et qui est transmise directement au navigateur avec un lien dans la page web de type href="http://123.45.67.89/blablabla.jpg". Du fait que c'est une image, si j'ai bien compris, il y a une exception à la politique "same origin" du navigateur et il y a bien ouverture d'un socket IP direct entre le navigateur et le serveur de l'image. Idem donc pour moi avec mon Arduino serveur de JSON.

Sauf dans le cas où cette vision n'est pas exacte, j'ai besoin de savoir comment va se comporter le couple navigateur - serveur intermédiaire lorsqu'il va décoder la page web et trouver un lien de type http://123.45.67.89/arduino1/capteur4.json. Est ce que ça va faire "tilt" et provoquer un rejet de la requête vers le serveur externe ? Au fait, qui détecte une violation de "same origin", le navigateur ou le serveur web ? Ou est ce que l'objet JSON va être considéré comme une image et passer comme une lettre à la poste ?

Ok donc vous n’êtes pas tout à fait dans le cas 1

OVH retourne une page qui contient du JavaScript et une XMLHttpRequest qui est exécuté sur le navigateur pour aller chercher de temps en temps un JSON sur un autre serveur que celui d’où provient la page (requête vers le capteur, pas vers OVH)

Dans ce cas vous tombez bien dans le CORS - plus de détails ici

C’est faisable mais galère suivant le navigateur client... y a t’il une bonne raison de ne pas prendre l’architecture 2 ? (Qui enlève tout problème de sécurité des capteurs)

Je ne sais pas si l'architecture 2 est réalisable avec les outils traditionnels proposés par les hébergeurs, à savoir html / php. Pour le peu de php que j'ai fait, je n'ai jamais lu qu'on pouvait programmer en php un client qui accède à un autre serveur. Ou alors il faut prendre chez l'hébergeur un serveur totalement open, qu'on peut programmer comme on veut, en Java, C, etc. . C'est plus cher, plus compliqué à mettre en oeuvre.

Cela dit, la question amène à se demander si, compte tenu du fait qu'on est capable de gérer des serveurs http réalisés sur ESP32 et de les rendre accessibles de n'importe où sur la toile, on ne peut pas aussi créer un serveur qui enverra les dites pages html/css/javascript. A la limite, un ESP32 avec une carte SD pour le stockage pourrait faire l'affaire.

Je peux aussi me demander si je n'ai pas intérêt à revenir à une architecture à deux niveaux, en intégrant ces services web sur l'ESP32 qui surveille les capteurs et fait les enregistrements de données. Dans une version actuellement opérationnelle de mon projet, au lieu d'ajax/json, l'ESP32 génère dynamiquement des fichiers images en .svg, qui constituent un calque transparent placé au dessus de l'image figée d'un graphique (axes, graduation, quadrillage). Et ça marche...

Bonjour

Je ne sais pas si l’architecture 2 est réalisable avec les outils traditionnels proposés par les hébergeurs, à savoir html / php. Pour le peu de php que j’ai fait, je n’ai jamais lu qu’on pouvait programmer en php un client qui accède à un autre serveur.

Dans l’architecture 2, souvent utilisée içi, les capteurs hébergent des clients qui publient ‘spontanément’ les données par des requêtes GET ou POST au serveur. S’il est parfois nécessaire de pouvoir paramétrer le capteur son client peut récupérer des consignes après chaque ‘notification’ de nouvelle valeur au serveur hébergé.

Un hébergeur proposant une instance de Broker MQTT (Mosquitto) ouvrirait une voie intéressante pour ce type d’application de capteurs communicants. (l’auto hébergement de Mosquitto sur Raspberry PI est facile et efficace)

La solution 2 est supportée pour quelques euros par mois chez OVH dans le cadre de l’hébergement web de base (j’ai ça depuis des années avec mon domaine). (vous pouvez commencer avec la version Perso à 3.59€ TTC par mois)

Dans votre hébergement web vous pouvez avoir autant de script PHP sur le serveur que vous voulez - donc par exemple un pour les capteurs et un pour l’interface utilisateur. Vous avez aussi une base de données SQL configurable pour servir de back end.

Un capteur envoie une requête GET ou POST vers le script capteur qui lit les données stocke cela dans la base de données et éventuellement envoie une information / demande en retour au capteur, ce qui permet une voie descendante sans avoir à ouvrir l’accès en entrée au lieu d’hébergement du capteur (utile aussi si vous êtes en 4G par exemple).

Pour voir les données vous prenez n’importe quel navigateur web ou écrivez une app pour smartphone qui balance des requêtes (un mode REST simple par exemple) vers le serveur OVH - charge au client de bien présenter les données (JavaScript ou l’application).

La solution MQTT conduit à prendre des abonnements chez des brokers, à stoker des messages de quelques dizaines d'octets pour envelopper une simple mesure qui tient sur deux octets. L'aspect marketing de la chose ne me convient guère.

La solution avec base de données chez le fournisseur d'accès, en fait du web 2.0 comme on en fait depuis 20 ans) est possible et je l'avais envisagée. Elle a l'avantage d'être intégrée dans de nombreux outils de réalisation de sites (wordpress...). D'ailleurs c'est peut être la solution vers laquelle je vais faire évoluer le projet. Mais le concept d'intégration mesure / stockage / production de données au navigateur distant me semblait séduisant et je voulais le tester.

On trouve quelque brokers MQTT gratuits mais la pérénité est sujette à caution.
Le broker Mosquitto auto hébergé sur un petit Raspberry Pi (ou analogue) tourne bien !
A ses côtés une petite base de données comme InfluxDB convient bien à cet usage.
On complète par ce que l'on veut , Grafana par exemple, NodeRED,......

mais effectivement ça ne parait pas ne coller parfaitement avec le reste du projet.

L'idée qui est derrière est que des outils comme les micro-systèmes à base d'ESP32, ou concurrents, intègrent des moyens de communication à distance comme le wifi ou bluetooth, par nature asynchrones et pas très performants en terme de débit, et des moyens de communication rapide plus limités en distance, comme le SPI ou l'I2C. Cela conduit à penser à des systèmes de contrôle-commande répartis en clusters, communiquant par SPI ou I2C, pour remplacer des faisceaux de câbles avec de la communication "hard real time", associés à de la communication WiFi ou Bluetooth pour de la communication asynchrone, le plus souvent orientée vers une interaction avec un humain ou un système distant. Il y a donc une réflexion à avoir, sur l'architecture, pour décider "qui fait quoi", "comment", et penser la solution globale de communication. La technologie "ajax" est l'un des composants utilisables dans ce cadre, d'où mon intérêt pour le tuto de J-M-L sur le sujet. Si ce tuto était complété par des exemples, dans le cadre d'architectures réparties, notamment en prenant en compte les protections Same-Origin et Cors, ce serait idéal :slight_smile:

Si ce tuto était complété par des exemples, dans le cadre d'architectures réparties, notamment en prenant en compte les protections Same-Origin et Cors, ce serait idéal

On tomberait dans un tuto HTML et javascript.... ça n'a plus rien à voir avec de l'Arduino.

Le lien donné précédemment Cross-origin resource sharing détaille tout ce qu'il faut pour gérer cela correctement (Access-Control-Allow-Origin, ...)

Côté architecture la notion de "capteur" dans le schéma #2 est conceptuelle. il peut s'agir d'un ensemble de micro-contrôleurs reliés entre eux avec différentes techniques / topologie. Il y a un "maître" cependant qui va décider quand exporter l'information vers le serveur central (OVH dans le dessin).

J-M-L:
Côté architecture la notion de "capteur" dans le schéma #2 est conceptuelle. il peut s'agir d'un ensemble de micro-contrôleurs reliés entre eux avec différentes techniques / topologie. Il y a un "maître" cependant qui va décider quand exporter l'information vers le serveur central (OVH dans le dessin).

Un système temps réel "dur" peut aussi fonctionner en autonomie, avec des communications rapides et prédéfinies entre processeurs (SPI, I2C), avec par exemple des échanges 25 fois par seconde, genre fréquence de rafraichissement d'un automate, et deux fois par jour avoir à répondre à des requêtes totalement asynchrones (Wifi, Bluetooth) parce qu'un humain a eu l'idée de consulter un état interne ou un historique ou encore de modifier un réglage.
Tout est possible mais la mémoire programme des modules (Arduino, ESP32) est limitée, donc il faut faire des choix. Sur l'échange rapide et périodique à formatage fixe, le maître est en général celui qui contrôle le temps dans le système. Sur les échanges lents et asynchrones, je préfère voir un module type Arduino en serveur et les fonctions qui le pilotent à haut niveau en client. Le client ayant l'initiative des échanges, dans les faits c'est lui "le maître".

Je ne vois pas trop votre point, on sort du cadre de la discussion sur CORS...

OK. La discussion a dérivé sur des contraintes plus générales d'architecture. Je crois que le mieux est que je prenne un forfait hébergement low cost pour essayer avec un vrai hébergeur de serveur web. Php et Mysql en perspective... ça va me ramener 20 ans en arrière :slight_smile:

Oui - l'architecture peut être à géométrie variable. il faut regarder le cahier des charges

si vous voulez jouer "pour de vrai" avec internet - ça ne coûte pas une fortune. Je trouve que l'hébergement "Perso" d'OVH est un bon moyen de commencer. Vous avez un accès FTP pour gérer vos fichiers à distance, accès aux logs, PHP et Python et MySQL 5.6, un certificat Let's Encrypt pour https et un back-up.

Sinon vous pouvez toujours avoir un petit serveur MAMP local qui permet aussi de se faire la main

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.