Fermer

juin 21, 2019

Prise en charge des demandes de proxy par CORS avec Express6 minutes de lecture

ReactT Dark_870x220


Lorsque notre serveur fait des demandes à un serveur qui réside dans un domaine différent, nous devons gérer le partage de ressources entre origines (CORS). Dans cet article, nous allons créer un proxy Express qui demandera en notre nom des données boursières à l'API IEX et émettra les en-têtes CORS appropriés afin que notre interface puisse y accéder sans problèmes.

Dans notre dernier article . nous avons construit une application React pour restituer l'historique des cours des actions. Tout fonctionnait bien, jusqu'à ce que nous rencontrions un problème lorsque nous tentions de frapper l'API IEX .

Notre interface (http: // localhost: 3000) et l'API IEX ( https: // api.iextrading.com/) vivent sous différents domaines, le navigateur applique donc la règle de même origine et bloque toute demande allant du premier au second.

Dans cet article, nous ' Vous apprendrez comment résoudre ce problème en construisant un proxy avec Express qui demandera des données sur les stocks à l'API IEX et émettra les en-têtes CORS appropriés afin que notre interface puisse accédez-y sans problèmes.

 Application de graphique boursier

Vous pouvez voir le code du proxy que nous allons construire sur ce rapport GitHub .

Qu'est-ce que la SRO ?

Le navigateur ne me fait pas de mal, ne me fait pas de mal … pas plus. 1965

La documentation du MDN sur CORS la définit comme suit:

Le partage de ressources d'origine croisée (CORS) est un mécanisme qui utilise des en-têtes HTTP supplémentaires pour indiquer à un navigateur de laisser une application Web s'exécuter une origine (domaine) est autorisée à accéder aux ressources sélectionnées d'un serveur situé à une autre origine. Une application Web crée une requête HTTP croisée lorsqu'elle demande une ressource dont l'origine (domaine, protocole et port) est différente de sa propre origine.

Etant donné que les en-têtes CORS doivent être inclus dans la réponse que nous recevons Sur le serveur, et comme nous n’avons aucun contrôle sur l’API IEX, nous devons créer notre propre serveur proxy qui transmet les demandes à l’API IEX, mais émet les en-têtes CORS appropriés pour que le navigateur ne bloque pas. n'importe quoi. Ensuite, nous devrons apporter des modifications à notre client afin qu’il frappe notre serveur au lieu d’IEX.

Création du serveur proxy

Nous allons créer notre serveur proxy avec Express un logiciel très populaire. Node framework d'application web. Nous adresserons des requêtes à l'API IEX en utilisant la requête un client HTTP simple. Pendant le développement, nous utiliserons également nodemon pour surveiller les modifications apportées à notre source et redémarrer automatiquement le serveur, ce qui nous fera gagner beaucoup de temps.

Commençons notre projet et installons toutes ces dépendances. :

 $ mkdir stock-chart-proxy-express
$ cd stock-chart-proxy-express
$ npm init -y
$ npm install --save express request
$ npm install --save-dev nodemon 

Pendant que nous y sommes, nous pouvons configurer le script start de notre package.json pour exécuter nodemon . ]:

 {
  "nom": "stock-chart-proxy-express",
  "version": "1.0.0",
  "privé": vrai,
  "scripts": {
    "start": "nodemon server.js"
  },
  "dépendances": {
    "express": "^ 4.16.4",
    "demande": "^ 2.88.0"
  },
  "devDependencies": {
    "nodemon": "^ 1.18.9"
  }
} 

Nous écrirons ensuite le serveur le plus simple possible dans ce fichier server.js :

 const express = require ('express');
const app = express ();
port constant = 3001;

app.get ('/', (req, res) => res.send ('Hello World!'));
app.listen (port, () => console.log (`http: // localhost: $ {port}`));; 19659020] Si nous  npm démarrons  et accédons à localhost sur le port 3001 avec notre navigateur, nous verrons  Hello World!  à l'écran. Si vous apportez des modifications au fichier  server.js vous verrez  nodemon  redémarrer automatiquement. Succès! 

Demandes à l'API IEX

Notre serveur proxy écoutera nos demandes et les transmettra à l'API IEX. Même si l'API IEX prend en charge une multitude d'options, nous ne tenons compte que de deux informations: le symbole saisi par l'utilisateur et la plage de dates sélectionnée par l'utilisateur.

Nous allons lire ces deux paramètres symbole et dans la requête et créez l'URL appropriée pour l'API IEX. Nous allons ensuite faire une demande à cette URL en utilisant la requête puis transmettre la réponse:

 app.get ("/", (req, res) => {
  // lire les paramètres de requête
  symbole de const = requete ["symbol"];
  const range = req.query ["range"];

  // craft URL IEX API
  const url = `https://api.iextrading.com/1.0/stock/market/batch?symbols=$ {symbol} & types = quote, chart & range = $ {range}`;

  // faire une demande à l'API IEX et transmettre la réponse
  demande (url) .pipe (res);
}); 

Traiter avec CORS

Si nous démarrons notre serveur maintenant et que nous pointons notre client React, nous verrons toujours les erreurs CORS. En effet, notre serveur n’émet pas encore d’en-têtes CORS. Même s'il existe des packages pour nous aider à traiter avec CORS, nos besoins sont si fondamentaux que nous pouvons émettre nous-mêmes l'en-tête nécessaire avec ce middleware simple:

 app.use ((req, res, next) => {
  res.header ("Accès-Contrôle-Autoriser-Origine", "*");
  suivant();
}); 

Désormais, l'en-tête Access-Control-Allow-Origin de l'ensemble des réponses est défini sur * nous allons donc autoriser les demandes de toutes origines.

to Heroku

Afin de déployer cette application sur Heroku nous souhaitons apporter deux modifications mineures:

La première concerne le port que notre serveur écoute. Nous l'avions codé en dur comme étant 3001 mais si vous lisez la documentation de Déploiement d'applications Node.js sur Heroku vous verrez ceci:

La commande dans un processus Web type doit être lié au numéro de port spécifié dans la variable d'environnement PORT . Si ce n'est pas le cas, le dyno ne commencera pas.

Notre déclaration du port devrait être remplacée par ceci:

 const port = process.env.PORT || 3001; 

Lorsque nous exécutons Heroku, nous utilisons la valeur définie par la variable d'environnement. Lorsque nous exécutons l'application localement, cette variable d'environnement n'est pas définie, nous allons donc revenir au port 3001 .

L'autre petit changement que nous souhaitons apporter est de limiter quelles origines peuvent faire des demandes à notre serveur. Nous autorisons * jusqu'à présent, mais nous souhaiterions peut-être procéder de la sorte:

 res.header ("Access-Control-Allow-Origin", process.env.ORIGIN || "| * "); 

Lorsque vous utilisez Heroku, vous pouvez définir la variable d’environnement ORIGIN sur quelque chose comme https://groundberry.github.io afin que seuls nos projets GitHub puissent y accéder. Lorsque nous exécutons l'application localement, la variable d'environnement n'est pas définie et nous allons donc revenir à * pour autoriser toutes les origines.

Voilà, nous sommes prêts à déployer le app to Heroku:

 $ heroku login
heroku $ crée un stock-chart-proxy
$ git push maître heroku
...
-----> application Node.js détectée
...
-----> Lancement ...
Sortie v9
https://stock-chart-proxy.herokuapp.com/ déployé à Heroku 

Si nous dirigeons maintenant notre application React vers https://stock-chart-proxy.herokuapp.com/ nous Nous verrons des demandes telles que https://stock-chart-proxy.herokuapp.com/?symbol=PRGS&range=5y être traitées sans problèmes liés à la SCRO, et tout fonctionnera comme prévu. Hourra!




Source link