Créer un serveur proxy Node.js en moins de 10 minutes !

August 11, 2020
Rédigé par
Nikolay Nikolov
Contributeur
Les opinions exprimées par les contributeurs de Twilio sont les leurs
Révisé par
Diane Phan
Twilion

Créer un serveur proxy Node.js en moins de 10 minutes !

Nous avons tous entendu le terme « proxy ». On pourrait croire qu'il s'agit d'une sorte de portail vers une nouvelle dimension tout droit sorti des films Matrix, mais il s'avère que c'est très réel... et très utile !

En résumé, un proxy est une application intermédiaire qui se trouve entre deux services (ou plus) et traite/modifie les requêtes et les réponses dans les deux sens. Cela semble compliqué, je le sais, mais essayons une analogie plus simple.

Imaginez le scénario suivant : vous rencontrez quelqu'un venant d'Espagne, mais vous ne parlez pas espagnol. Que faites-vous ? Eh bien, vous vous souvenez que votre ami Santiago connaît à la fois l'espagnol et le français et peut traduire pour vous.

des gens qui se parlent dans des langues différentes et qui demandent à l'autre sa musique préférée

Le processus se présente comme suit :

  1. Vous dites quelque chose à Santiago en français
  2. Santiago le traduit en espagnol dans sa tête et le dit en espagnol à votre nouvel ami
  3. Votre nouvel ami répond à Santiago en espagnol
  4. Santiago le traduit ensuite dans sa tête et vous dit la réponse en français

Santiago dans ce cas sert de proxy entre vous et votre nouvel ami. Vous ne pouvez pas parler directement les uns avec les autres, mais grâce au traducteur, vous pouvez relayer des messages (c'est-à-dire des requêtes et des réponses) et avoir une conversation !

OK, maintenant que nous savons ce qu'est un proxy, quels en sont les cas d'utilisation ? En voici quelques-uns que nous, chez Twilio, trouvons vraiment utiles :

  • Autorisation : transmettre uniquement les requêtes autorisées à accéder à un service
  • Équilibrage de la charge : répartir les requêtes de manière égale entre plusieurs instances
  • Journalisation : enregistrer toutes les requêtes envoyées à un service d'API back-end
  • Et bien plus encore…

Maintenant que vous savez ce qu'est un proxy et en quoi il est utile, construisons-en un simple à l'aide de Node.js !

Conditions préalables

Pour continuer, vous devez installer Node.js et Yarn, qui sont disponibles sur les distributions Mac, Windows et Linux.

Créer le proxy Node.js simple

En quelques étapes faciles, nous allons créer un proxy simple dans Node.js qui peut transmettre des requêtes à plusieurs serveurs/points de terminaison différents !

Le code complet - qui sera implémenté étape par étape - est disponible sur GitHub ici.

Initialiser le projet

Commençons par lancer un nouveau projet Node :

yarn init

Ceci génère un fichier package.json qui contient une configuration de projet de base. La commande affiche plusieurs questions (nom, version, description, etc.) à votre intention. Vous pouvez sélectionner « Entrée » pour toutes les questions afin d'accepter les valeurs par défaut (par exemple, le point d'entrée est index.js par défaut).

Installer les dépendances

Nous avons besoin de quelques packages pour que le proxy fonctionne :

que nous pouvons installer en exécutant :

yarn add express http-proxy-middleware morgan

Définir une commande de démarrage

Nous devons ajouter une commande start à notre projet. Après une petite modification, votre fichier package.json ressemble à ceci (selon le moment où vous installez ces packages, certains numéros de version peuvent différer, mais leur fonctionnalité principale devrait rester la même. Si le comportement est radicalement différent, consultez la documentation la plus récente) :

{
 "name": "simple-nodejs-proxy",
 "version": "1.0.0",
 "main": "index.js",
 "license": "MIT",
 "dependencies": {
   "express": "^4.17.1",
   "http-proxy-middleware": "^1.0.5",
   "morgan": "^1.10.0"
 },
 "scripts": {
   "start": "node index.js"
 }
}

Si nous ajoutons maintenant un fichier index.js vide, nous pouvons exécuter le projet via :

yarn start

Ceci devrait exécuter le fichier. Comme le fichier est vide, la sortie de la console doit également être vide.

Mais assez de configurations. Utilisons le proxy pour faire quelques requêtes !

Créer un proxy simple

C'est là que les éléments intéressants commencent. Ouvrez le fichier index.js et ajoutez les importations nécessaires :

const express = require('express');
const morgan = require("morgan");
const { createProxyMiddleware } = require('http-proxy-middleware');

Nous pouvons maintenant créer un serveur express de base et définir certaines constantes que nous utiliserons plus tard :

// Create Express Server
const app = express();

// Configuration
const PORT = 3000;
const HOST = "localhost";
const API_SERVICE_URL = "https://jsonplaceholder.typicode.com";

Avant d'implémenter la logique proxy, nous pouvons ajouter le middleware morgan qui consigne les requêtes entrantes :

// Logging
app.use(morgan('dev'));

Pour pouvoir tester que nous utilisons le proxy uniquement sur ce que nous voulons, ajoutons un point de terminaison /info fictif qui ne transmet pas la requête, mais renvoie plutôt une réponse texte simple :

// Info GET endpoint
app.get('/info', (req, res, next) => {
   res.send('This is a proxy service which proxies to Billing and Account APIs.');
});

Avant de définir les points de terminaison proxy, ajoutons également un middleware de gestion des autorisations simple qui envoie l'erreur 403 (interdit) si l'en-tête d'autorisation est manquant :

// Authorization
app.use('', (req, res, next) => {
   if (req.headers.authorization) {
       next();
   } else {
       res.sendStatus(403);
   }
});

Nous définissons ensuite le point de terminaison du proxy. Nous voulons utiliser le proxy pour toutes les requêtes commençant par /json_placeholder vers la fameuse API JSONPlaceholder (une simple API factice qui contient plusieurs points de terminaison prenant en charge toutes les méthodes HTTP). Nous définissons également un pathRewrite de sorte que /json_placeholder soit omis lorsqu'il est transmis à l'API :

// Proxy endpoints
app.use('/json_placeholder', createProxyMiddleware({
   target: API_SERVICE_URL,
   changeOrigin: true,
   pathRewrite: {
       [`^/json_placeholder`]: '',
   },
}));

Ainsi, lorsque nous envoyons une requête à localhost:3000/json_placeholder/posts/1, l'URL est réécrite dans <API_SERVICE_URL>/posts/1 ( dans ce cas : https://jsonplaceholder.typicode.com/posts/1), supprimant ainsi /json_placeholder dont l'API n'a pas besoin.

Enfin, nous démarrons le serveur configuré avec cet appel de fonction :

// Start the Proxy
app.listen(PORT, HOST, () => {
   console.log(`Starting Proxy at ${HOST}:${PORT}`);
});

Exécuter le proxy

Démarrons le proxy avec la commande suivante :

yarn start

Vous devez obtenir une sortie semblable à ce qui suit :

yarn run v1.22.4
$ node index.js
[HPM] Proxy created: /  -> https://jsonplaceholder.typicode.com
[HPM] Proxy rewrite rule created: "^/json_placeholder" ~> ""
Starting Proxy at localhost:3000

Le proxy doit maintenant être en cours d'exécution et si nous ouvrons un deuxième terminal et envoyons une requête GET à /info :

curl localhost:3000/info

Nous devrions recevoir une réponse de notre proxy. Et, sans surprise, nous avons :

This is a proxy service which proxies to JSONPlaceholder API.

OK, c'est très bien, mais nous ne voulons pas recevoir des points de terminaison GET ennuyeux, nous voulons utiliser le proxy !

Pour tester le proxy, nous pouvons envoyer une nouvelle requête GET comme suit :

curl localhost:3000/json_placeholder/posts/1

l&#x27;homme dit oh non

Oh, non ! Ceci renvoie :

Forbidden

Ne vous inquiétez pas, c'est ce que nous attendions, car nous avons inclus le middleware d'autorisation qui exige que chaque requête contienne un en-tête d'autorisation. Faites donc cette petite modification (vous pouvez même la remplacer par votre nom car, en raison de la simplicité de notre étape d'autorisation, chaque nom fonctionnera !) :

curl -H "Authorization: nikolay" localhost:3000/json_placeholder/posts/1

Cela nous donne :

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

Hourra ! Votre première requête avec proxy ! Nous pouvons même essayer ceci avec une requête POST :

curl -X POST -H "Authorization: real_user" --data '{"title": "Build a Node.js Proxy Server in Under 10 minutes!","body": "We have all heard the term "proxy"...",userId="1"}' localhost:3000/json_placeholder/posts

La requête POST fonctionne comme prévu :

{
  "{\"title\": \"Build a Node.js Proxy Server in Under 10 minutes!\",\"body\": \"We have all heard the term "proxy"...\",userId": "\"1\"}",
  "id": 101
}

Pour le code complet, consultez le référentiel GitHub.

Et ensuite, pour les serveurs proxy Node.js ?

Il s'agit d'une version extrêmement simple d'un proxy. Elle est minimale, mais elle fonctionne ! Selon votre cas d'utilisation, vous pouvez l'étendre en utilisant les méthodes suivantes :

http-proxy-middleware est une bibliothèque simple mais puissante, et il existe de nombreuses propriétés que vous pouvez modifier pour atteindre vos objectifs spécifiques. Consultez donc sa documentation pour créer quelque chose de plus complexe.

Conclusion

Peut-être qu'avant de lire cet article, vous ne saviez pas ce qu'était un proxy ou vous pensiez qu'il était vraiment difficile d'en construire un vous-même. Comme vous pouvez le voir, c'est tout le contraire ! Certes, celui que nous avons créé est simple, mais maintenant vous connaissez les bases et vous avez tout ce dont vous avez besoin pour le rendre plus complexe, plus efficace ou peut-être tout simplement un peu plus amusant ! Alors, lancez-vous et frimez auprès de vos collègues et amis grâce à vos compétences en matière de proxy récemment acquises !

Nikolay Nikolov est ingénieur en informatique stagiaire au sein de l'équipe Super SIM de Twilio. Il aime explorer les concepts Web et de machine learning, ainsi que partager ses trouvailles avec d'autres passionnés de technologie. Vous pouvez contacter Nikolay sur LinkedIn ou consulter son site Web.