Fermer

décembre 2, 2021

Comment protéger votre clé API en production avec Next.js API Route —


Résumé rapide ↬

La création d'applications Jamstack sur le Web est un défi de taille. Dans cet article, Caleb Olojo explique comment utiliser Next.js pour amorcer votre application en toute sécurité.

Les développeurs front-end doivent interagir avec des API privées ou publiques dont la méthode d'autorisation nécessite une clé secrète/clé API qui permet aux développeurs d'utiliser ces API. La ou les clés sont importantes, d'où la nécessité de stocker/protéger la ou les clés. La création d'une variable d'environnement qui stocke la clé est la solution incontournable que la plupart des développeurs ont tendance à adopter, mais il y a un hic. La variable d'environnement ne protège pas la ou les clés de quiconque connaît les outils de développement de son navigateur. C'est pourquoi nous devons utiliser nos clés côté serveur lorsque nous écrivons nos appels d'API.

Dans cet article, nous utiliserons Next.js pour amorcer notre application. Cela ne signifie pas que la bibliothèque create-react-app ne fonctionnera pas. Vous pouvez utiliser celui que vous trouvez pratique. Nous utilisons Next.js en raison des nombreux avantages qui l'accompagnent. (Vous pouvez en savoir plus sur Next.js ici.)

Commençons par installer les dépendances dont nous avons besoin dans ce projet. Nous allons commencer par créer une application Next.js. La commande ci-dessous le fait pour nous :

npx create-next-app [name-of-your-app]

Nous utiliserons la bibliothèque native JavaScript "Fetch API" pour obtenir des données de l'API. Nous ne couvrirons pas une grande partie de l'aspect style dans cet article. (Si vous souhaitez jeter un œil à un exemple de projet que j'ai construit à l'aide du modèle de route de l'API Next.js, vous pouvez trouver le référentiel ici.)

Voyons maintenant la structure du fichier de l'application. Nous allons nous concentrer sur les fichiers importants nécessaires dans cette application, donc ce sera concis.

|--pages
| |-- api
| | |-- serverSideCall.js
| |-- _app.js
| |-- index.js
|__ .env.local

Répartition des fichiers dans la structure de l'application

Dans cette section, nous allons voir les différents fichiers qui composent l'architecture de ce projet, et leurs fonctions respectives ci-dessous.

Le répertoire pages est l'endroit où se déroule tout le routage de l'application. Il s'agit d'une fonctionnalité prête à l'emploi de Next.js. Cela vous évite le stress de coder en dur vos routes indépendantes.

  • pages/api
    Le répertoire api vous permet d'avoir un backend pour votre application Next.js, dans la même base de code, au lieu de la manière habituelle de créer des référentiels séparés pour vos API REST ou GraphQL et les déployer sur des plates-formes d'hébergement backend comme Heroku, etc.

    Avec le répertoire apichaque fichier est traité comme un point de terminaison d'API. Si vous regardez le dossier apivous remarquerez que nous avons un fichier appelé user.js.

    Ce fichier devient un point de terminaison, ce qui signifie un appel API peut être effectué en utilisant le chemin d'accès au fichier comme URL de base.

const getData = async() => {
  fetch("/api/users")
   .then(réponse => réponse())
   .then(response => console.log(response.data))
   .catch(err => console.log(err)
}
  • pages/_app.js
    C'est là que tous nos composants sont attachés au DOM. Si vous jetez un œil à la structure des composants, vous verrez que tous les composants sont également transmis en tant que pageProps aux accessoires Component.
function MyApp({ Component, pageProps }) {
  revenir (
    
      
        
        
      
      
    
  );
}

export default MyApp;

Si vous êtes nouveau sur Next.js, veuillez consulter cet article qui vous guidera tout au long du processus.

  • index.js
    C'est la route par défaut dans le dossier des pages. Lorsque vous exécutez la commande ci-dessous, il démarre un serveur de développement et le contenu de index.js est affiché sur la page Web.
npm run dev
  • .env.local
    It est l'endroit où nous stockons la clé API qui nous permettra de consommer cette API.

Plus après le saut ! Continuez à lire ci-dessous ↓

L'appel d'API côté serveur

La section précédente vous a présenté les fichiers avec lesquels nous allons interagir et leurs fonctions spécifiques. Dans cette section, nous allons passer à la façon dont nous pouvons utiliser l'API.

La raison pour laquelle nous écrivons l'appel d'API côté serveur est pour sécuriser notre clé API, et Next.js en fait déjà un simple tâche pour nous. Avec les routes API dans Next.js, nous pouvons effectuer nos appels API sans craindre que nos clés API ne soient révélées côté client.

Vous vous êtes peut-être demandé quelle était l'essence de la variable d'environnement dans Le fichier .env est, dans ce scénario.

La variable d'environnement (qui est notre clé API) ne peut être disponible qu'en mode développement.

C'est pourquoi nous pouvons faire quelque chose comme process.env.api_keyet accédez à la variable d'environnement.

Mais, au moment où vous déployez votre application sur des plateformes comme Netlify ou Vercel, le mode passe à productionce qui rend l'objet Node.js process indisponible côté client.

Maintenant que vous avez vu la raison pour laquelle vous devez écrire un appel API côté serveur. Allons-y tout de suite.

exporter la fonction asynchrone par défaut serverSideCall(req, res) {
    const {
      requête : { firstName, lastName },
    } = req;

    const baseUrl = `https://api.example-product.com/v1/search?
        lastName=${lastName}&firstName=${firstName}
        &apiKey=${process.env.KEY}
    `;
    réponse const = wait fetch (baseUrl);
    res.status(200).json({
    données : réponse.données,
  });
}

Dans l'extrait ci-dessus, nous avons créé une fonction asynchrone appelée serverSideCall. Il prend deux arguments, req qui signifie "requête" en entier, et res qui est "réponse" en entier.

L'argument req possède des propriétés (ou "middlewares" comme l'appellent la documentation Next.js) auxquelles on peut accéder lorsque nous utilisons notre API, l'une d'entre elles est req.query.

Vous allez notez que nous avons déstructuré la propriété query dans l'extrait ci-dessus, nous devrions donc maintenant pouvoir transmettre ces variables en tant que valeurs aux propriétés de requête du point de terminaison de l'API. Jetez-y un œil ci-dessous.

Remarque : Vous pouvez en savoir plus sur les middlewares intégrés fournis avec l'argument req ici .

const {
  requête : { firstName, lastName },
} = req;

L'URL de base prend les propriétés de requête déstructurées comme valeurs et la apiKey est obtenue à partir du fichier .env via le Node.js process .

Les propriétés de requête déstructurées sont considérées comme des requêtes qui seront envoyées depuis les valeurs d'entrée du composant de formulaire (que nous allons créer dans la section suivante) à l'API, une fois reçue, nous obtenons un réponse qui correspond à la demande que nous avons faite.

const baseUrl = `https://api.kelvindata.com/rest/v1/searchv2? lastName=${lastName}&firstName=${firstName}&apiKey=${process.env.KEY}`;

Le prochain processus que la fonction doit terminer est la réponse de l'appel d'API asynchrone. L'extrait ci-dessous affecte l'appel d'API que nous effectuons avec la bibliothèque axios à une variable, response.

Sur la ligne suivante, l'argument res utilise la méthode status qui est utilisée pour nous envoyer une réponse JSON, alors nous pouvons affecter la variable de réponse en tant que propriété de data.

const réponse = wait axios.get (baseUrl);
res.status(200).json({
  données : réponse.données,
});

Vous pouvez en savoir plus sur les différents codes d'état HTTP ici.

Utilisation pratique de la fonction API côté serveur

Dans cette section, nous examinerons comment nous pouvons utiliser l'appel d'API côté serveur en créant un formulaire avec deux champs de saisie. Les valeurs d'entrée seront envoyées en tant que paramètres de requête au point de terminaison de l'API.

import React from "react" ;

Indice const = () => {
  const [data, setData] = React.useState([]);
  const [firstName, setFirstName] = React.useState("");
  const [lastName, setLastName] = React.useState("");

  const getuserData = async () => {
    // l'appel api va ici
  } ;

  const handleSubmit = (e) => {
     e.preventDefault();
     getuserData();
  } ;

  revenir (
     
       
setFirstName(e.target.value)} /> setLastName(e.target.value)} />
); } ; export default Index;

Étant donné qu'il s'agit d'un composant React qui reçoit des données d'un point de terminaison d'API, il doit avoir son propre état interne. L'extrait ci-dessous montre comment nous avons défini les différentes variables d'état avec React Hooks.

const [userData, setUserData] = React.useState([]);
const [firstName, setFirstName] = React.useState("");
const [lastName, setLastName] = React.useState("");

Les variables firstName et lastName stockeront les valeurs de texte saisies dans le champ de saisie par quiconque dans le variables d'état.

La variable d'état data nous aide à stocker la réponse que nous obtenons de l'appel d'API dans un tableau, nous pouvons donc utiliser la méthode JavaScript map() pour rendre la réponse sur la page Web.

Ci-dessous, nous utilisons axios pour obtenir des données du point de terminaison de l'API. Mais ici, l'URL de base n'est pas une URL typique https://c'est plutôt le chemin d'accès au fichier où nous avons effectué l'appel d'API côté serveur auparavant.

const getuserData = async ( ) => {
fetch(`/api/usersfirstName=${firstName}&lastName=${lastName}`, {
       en-têtes : {
         Acceptez : "application/json",
       },
})
  .then((réponse) => réponse)
  .then((réponse) => {
    setData(response.data.data);
    console.log(response.data.data);
  })
  .catch((err) => console.log(err));
};

Le même processus dans le fichier serverSideCall.js est répété, mais cette fois-ci avec les en-têtes d'API de récupération nécessaires et l'affectation des variables d'état d'entrée aux paramètres de requête de l'API.

Conclusion

Il existe d'autres approches qui peuvent aider à réaliser cet exploit. En voici quelques-uns :

  • Créer des fonctions Netlify Lambda qui aideront à protéger vos clés API côté client.
    Cette approche le fait à peu près pour vous, mais si vous n'êtes pas fan de l'écriture ainsi beaucoup de code, cela vous aidera à faire les petites choses. La route API Next.js est votre meilleur pari pour résoudre ce problème.
  • Rendu du serveur avec Next.js pour masquer les clés API.
    Dans cette vidéo, Ijemma Onwuzulike explique comment faire cela avec le rendu côté serveur. Je vous recommande de le vérifier.

Merci d'avoir lu cet article. Veuillez le partager et n'hésitez pas à jeter un œil à un exemple de projet pratique que j'ai construit à l'aide de la route de l'API Next.js ici.

Further Reading On Smashing Magazine

Smashing Editorial (vf, yk, il)




Source link