Site icon Blog ARC Optimizer

Implémentation d'OAuth 2 à l'aide de Node.js


OAuth 2.0 est le protocole standard de l'industrie pour l'autorisation. Dans cet article, nous allons implémenter OAuth 2 à l'aide de l'environnement d'exécution Node.js.

Dans cet article, nous allons parcourir l'implémentation d'OAuth sur un serveur Node.js à l'aide de l'API Google pour demander l'autorisation d'accéder et d'afficher le profil. données d'un propriétaire de compte Google. Nous nous concentrerons sur les concepts de base impliqués sans utiliser de bibliothèques qui résument les complexités. Sans plus tarder, plongeons-y.

Un peu sur les types d'octroi OAuth

Les types d'octroi ou les flux OAuth définissent les nombreuses façons dont notre application peut obtenir un jeton d'accès. Voici une liste des différents types d'octroi disponibles :

  • Type d'octroi des informations d'identification du client : il est utilisé par les clients pour obtenir un jeton d'accès en dehors du contexte d'un utilisateur.
  • Type d'octroi du mot de passe : ici, le client reçoit des informations de connexion, c'est-à-dire un nom d'utilisateur et un mot de passe, par le propriétaire de la ressource. Le client utilise ensuite ces informations pour obtenir un jeton d'accès qui n'est pas recommandé mais utilisé dans les applications OAuth héritées. le client, mais plutôt le serveur d'autorisation authentifie l'utilisateur et, sur la base du consentement de l'utilisateur, émet un jeton d'autorisation au client, que le client utilisera ensuite pour obtenir le jeton d'accès pour accéder à la ressource.

D'autres types d'octroi incluent les types d'attribution de jeton implicite et d'actualisation. Pour en savoir plus, n'hésitez pas à consulter ici.

Exigences

Voici les exigences pour ce message :

  • Node.js
  • HTTP (requêtes et réponses)
  • RESTful API

Configuration de l'environnement

Collez la commande suivante dans le terminal pour créer un répertoire de travail, initialiser Node Package Manager et créer un fichier server.js qui contiendra notre code serveur.

 mkdir oauthapp
cd oauthapp
npm init --y
toucher serveur.js utils.js

Ensuite, installez les dépendances nécessaires au projet :

  • Express : utilisé pour créer un serveur Web et écouter les requêtes
  • Axios : un client basé sur des promesses utilisé pour effectuer des requêtes HTTP
  • Dotenv : utilisé pour analyser les variables d'environnement du fichier .env créé précédemment
npm i express dotenv axios

Maintenant, nous devons créer un serveur express simple. Collez le code suivant dans le fichier server.js.

const express = require ('express"http://www.telerik .com/);
port const=4000;

app.get ('/auth"http://www.telerik.com/, async (req res) => {
  res.envoyer("route d'authentification"http://www.telerik.com/)
});
application.écouter(port)

Le code ci-dessus démarre un serveur de nœud simple qui enregistre un point de terminaison unique s'exécutant sur le port 4000. Visitez localhost:4000/auth sur votre navigateur pour accéder au serveur.

Réponse de notre serveur de nœud

Cela fonctionne mais ne fait pas grand-chose pour nous. Alors, où allons-nous partir d'ici? J'ai déjà abordé les types de subventions et les différents types de subventions disponibles ; c'est ce qui décide du prochain mouvement.

Flux OAuth

Le diagramme ci-dessus décrit la série d'événements qui doivent se produire avant que notre application cliente puisse accéder à la ressource protégée. Vous trouverez ci-dessous des représentations plus précises de ces étapes.

  1. Enregistrez votre application cliente sur le serveur d'autorisation pour obtenir des informations d'identification. le consentement de l'utilisateur.
  2. Configurez le point de terminaison à utiliser pour obtenir le jeton d'autorisation.
  3. Utilisez ce jeton d'autorisation pour obtenir un jeton d'accès.
  4. Utilisez le jeton d'accès pour obtenir la ressource protégée (données de profil utilisateur).

1. Enregistrez votre application cliente sur le serveur d'autorisation pour obtenir des informations d'identification OAuth

Le schéma ci-dessus montre que nous construisons l'application cliente et qu'elle est impliquée dans plusieurs allers-retours HTTP avec le propriétaire de la ressource et le serveur d'autorisation (le serveur Google OAuth dans ce cas ).

Cela signifie que nous devons donner à notre application Node.js la possibilité de communiquer avec le serveur d'autorisation ; nous le faisons en enregistrant notre application et en obtenant un identifiant client et un secret ; cela garantit que le serveur d'autorisation connaît notre application.

Accédez à Google Cloud Console et créez une application, puis configurez son écran de consentement OAuth et les étendues que vous souhaitez autoriser.

Créer une application sur Google Cloud Console

Configurer votre Écran OAutho et activez les étendues

Une fois que cela a réussi, rendez-vous dans la section des informations d'identification et créez des informations d'identification. Commencez par sélectionner le type d'informations d'identification souhaitées.

Obtenir des informations d'identification OAuth

Ensuite, remplissez le nom de l'application, en fournissant des informations sur le le nom de domaine de l'application et l'URI de redirection, que le serveur d'autorisation utilisera pour envoyer le jeton d'autorisation.

Remarque : Dans les applications prêtes pour la production, l'URL de redirection n'est acceptée que si elle s'exécute sur HTTPS, mais les applications d'hôte local ne le font pas. Vous n'avez pas cette restriction.

Fournissez des informations sur votre application sur Google Cloud

Une fois cela fait, copiez l'ID client et secret client avec le chemin dans l'URI de redirection, c'est-à-dire /api/callback dans ce cas, puis dirigez-vous vers le fichier .env dans le répertoire de votre serveur et créez l'environnement variables.

CLIENT_APP_ID=542685936115-t6b82l8f0s3S9 88pc3me5adh.apps.googleusercontent.com
CLIENT_APP_SECRET=NF4sJq980cO_qWT_KokKMumfR
REDIRECT_URI=/api/rappel

Avec cela en place, l'application dispose désormais d'informations d'identification valides pour communiquer avec le serveur d'autorisation.

Configurez maintenant le point de terminaison utilisé pour rediriger l'utilisateur vers le serveur d'autorisation pour s'authentifier et demander le consentement de l'utilisateur.

Tout d'abord, accédez à utils.js et insérez le code suivant.

const query_string = require ('querystring"http://www.telerik.com/)[19659027] ;
const google_auth_token_endpoint ='https://accounts.google.com/o/oauth2/v2/auth"http://www.telerik.com/ ;
const query_params = {
  client_id : processus.env.CLIENT_APP_ID,
  redirect_uri : `http://localhost:4000${processus.env.REDIRECT_URI} ]`,
};

  const auth_token_params = {
    ...query_9090query_9010query_9010query_params
    response_type : 'code"http://www.telerik.com/,
  };

const étendues = [[19659026]'profil"http://www.telerik.com/, 'email"http://www.telerik.com/, 'openid"http://www .telerik.com/];

  const request_get_auth_code_url = `${google_auth_token_endpoint}5? 19659094]${query_string.chaîner (auth_token_params)}&scope=[904]$90&scope=[904]$90[9419026]&scope=[904]$90 .rejoindre (' "http://www.telerik.com/)}` ;
module.exporte ={request_get_auth_code_url}

Le code ci-dessus utilise le module de chaîne de requête, puis définit le point de terminaison de l'API Google pour obtenir un jeton d'accès et, enfin, crée un objet composé avec les clés suivantes et leur signification.

  • Redirect URI : le point de terminaison utilisé par le serveur d'autorisation pour émettre le jeton d'autorisation
  • Type de réponse : doit être défini sur code pour garantir que le serveur émet un jeton d'autorisation
  • ID client : un identifiant unique utilisé pour identifier notre application sur le serveur d'autorisation

Une variable appelée scopes est ensuite définie, qui contient un tableau de chaînes qui spécifie le segment d'informations de l'utilisateur auquel nous voulons accéder. Enfin, une URL composée du point de terminaison de l'API Google et d'une chaîne de requête formée à partir de l'objet composé et des portées définies ci-dessus est liée à une variable et finalement exportée.

Nous devons maintenant modifier le fichier server.js.

 const express=....
const utils = require ('./utils"http:/ /www.telerik.com/);

app.get ('/auth"http://www.telerik.com/, async (req res) => {
  essayer {
    res.redirection (utils.request_get_auth_code_url);
  } catch  19659027]) {
    res.sendStatus (500);
    console.journal (erreur.message);
  }
}))))))) 

Tout d'abord, nous avons tout importé du fichier utils.js. Dans notre point de terminaison /authnous redirigeons l'utilisateur vers le serveur d'autorisation à l'aide de l'URL importée précédemment, enregistrons le code et redémarrons le serveur.

.

Visite de localhost : 4000/auth

3. Configurez le point de terminaison pour obtenir le jeton d'autorisation

Aucun URI de redirection sur notre serveur pour gérer la demande de serveur d'autorisation

Après l'authentification réussie de l'utilisateur, l'application affiche toujours une erreur. Le serveur d'autorisation envoie une requête GET à l'URI de redirection fourni dans la requête précédente, mais nous n'avons pas défini de point de terminaison sur notre serveur pour le gérer.

Dans votre fichier server.jsinsérez le suivant.

app.get("/auth"http://www.telerik.com/,(req ,res)=>{.....})
app.get (processus.env.REDIRECT_URI, async (0[14945q](0 , res) => {
  
  const autorisation_token = req.[949[524]5query5. ]code;
});

Le code ci-dessus utilise l'URL de redirection des variables d'environnement déclarées précédemment pour définir le point de terminaison utilisé pour gérer la demande entrante du serveur d'autorisation et obtient le jeton d'autorisation à partir des paramètres de requête de la demande.

4. Utilisez ce jeton d'autorisation pour obtenir un jeton d'accès

Nous avons maintenant obtenu le jeton d'autorisation. Il est temps d'échanger ce jeton contre un jeton d'accès. Incluez les éléments suivants dans votre fichier utils.js.

const query_string=require(...)
const  axios = require("axios"http://www.telerik.com/)
const google_access_token_endpoint =1 ]'https://oauth2.googleapis.com/token"http://www.telerik.com/;

const query_params={...  19659025]{
    ...query_params,
    client_secret : processus.env.CLIENT_APP_SECRET,
    code : code_auth,
    grant_type : 'authorization_code"http://www.telerik.com/,
  };
  return wait axios ([19659027]{
    méthode : 'post"http://www.telerik.com/,
    URL : `${google_access_token_endpoint} ?${chaîne_requête.[19655590].. access_token_params)}`,
  });
}
}
}
}
}
}
}
}
}
}
};

module.exporte = {request_get_auth_code_url, get_access_token};

Dans le code ci-dessus, nous avons d'abord importé le module Axios. Ensuite, nous avons défini le point de terminaison utilisé pour obtenir le jeton d'accès. Après cela, nous avons défini une méthode qui attend le jeton d'autorisation comme paramètre, puis enfin, nous avons créé un objet avec plusieurs clés telles que l'identifiant client, le secret client ainsi que d'autres paramètres plus récents, notamment :

  • Secret client  : une chaîne utilisée pour signer notre demande.
  • Grant type : comme indiqué précédemment, il s'agit d'un ensemble de codes d'autorisation. Ce champ peut contenir un mot de passe ou tout autre type d'octroi en fonction des besoins de l'application.
  • Code : contient le code d'autorisation.

En interne, cette méthode envoie une demande de publication au point de terminaison pour obtenir le jeton d'accès. .

Enfin, nous avons ajouté la méthode à notre liste d'exportations.

Dans le fichier server.jsincluez le code suivant.

app.get[19659025](processus.env.REDIRECT_URI, async (req,[4]res  => {
  
    const authentication_token = req.requête.code2 ;2 ; 19659025] { Const   =  Await  Utils .  Get_access_Token   ( Authoration_Token  Code  );
      console.journal ({données : réponse.données})[17]6590 19659282]const {access_token} = réponse.données ;
    } catch[590] erreur) {
      res.sendStatus (500);
    }
});

Le code ci-dessus utilise la méthode définie dans le fichier utils.js pour demander le jeton d'accès. La réponse à cette requête contient plusieurs valeurs telles que :

  • Access token : utilisé pour obtenir la ressource
  • Refresh token (optionnel) : utilisé pour obtenir un autre access token si celui en cours expire

5. Utiliser le jeton d'accès pour obtenir les données du profil utilisateur

Enfin, nous utilisons le jeton d'accès pour obtenir les ressources de l'utilisateur de la même manière que nous l'avons fait avant de mettre à jour notre fichier utils.js avec ce qui suit.

const get_profile_data = async access_token => {
  return wait axios ({
    méthode : 'post"http://www.telerik.com/,
    URL : `https://www.googleapis.com/oauth2/v3/userinfo?alt=json&access_token=${access_token}`,
  });
};
Module .  Exportations  =  { request_get_auth_code_url  Get_access_Token  get_profile_data } ; ;

Le code ci-dessus définit une autre méthode qui reçoit le jeton d'accès en tant que paramètre, puis effectue une requête de publication HTTP pour accéder aux données de profil de l'utilisateur dans l'URL de la requête.

Nous avons défini et exporté une méthode que nous utiliserions pour obtenir les informations du profil de l'utilisateur. Ensuite, nous importons et utilisons maintenant cette méthode dans notre fichier server.js comme suit.

app.get (process. ]env.REDIRECT_URI, async (req, res) => =>=>=>=> const autorisation_token = requête.requête ;
  console.journal ({auth_server_response : autorisation_token});{1965915];{19659156] ;{19659156 19659353] Const  Réponse  =  Aide . . Get_access_Token   ( Authorize_Token  Code ) )  ;
  
    const {access_token} = réponse.données;
    
    const utilisateur 19659036] Attends .   Get_Profile_Data   ( Access_Token ) ;  user_data  =  Utilisateur  .données;
    res.envoyer (`
      

bienvenue

${user_data.nom} <img src="http://www.telerik.com/${user_data.image}" alt="user_image" /> `
); console.log (user_data); } catch (erreur0)0 console.journal (erreur.message) ; res.sendStatus (500); } });

Nous obtenons maintenant les données de profil de l'utilisateur (ressource) et, pour ce cas d'utilisation simple, nous envoyons le nom et la photo de l'utilisateur dans des chaînes de modèle.

Remarque : Des identifiants tels que des jetons d'accès, des jetons de demande et les ressources doivent être conservées en toute sécurité.

Conclusion

Nous avons implémenté le fonctionnement interne du flux d'autorisation OAuth. Les problèmes de sécurité sont également primordiaux pour s'assurer qu'un attaquant n'intercepte pas les informations d'identification. Une autre variante du flux de code d'autorisation est la mise en œuvre avec PKCE "pixie" pour ajouter une autre couche de sécurité au flux de code d'autorisation normal. Cet article vous donne une base solide pour développer et intégrer différents fournisseurs OAuth dans vos futurs projets.




Source link
Quitter la version mobile