Activer l’authentification dans votre propre application web Node à l’aide d’Azure Active Directory B2C
Dans cet article, vous allez apprendre à ajouter l’authentification Azure Active Directory B2C (Azure AD B2C) dans votre propre application web Node.js. Vous permettez aux utilisateurs de se connecter, de se déconnecter, de mettre à jour leur profil et de réinitialiser leur mot de passe à l’aide des flux d’utilisateurs Azure AD B2C. Cet article utilise la bibliothèque d’authentification Microsoft (MSAL) pour Node afin de simplifier l’ajout de l’authentification à votre application web Node.
L’objectif de cet article est de remplacer l’exemple d’application que vous avez utilisé dans Configurer l’authentification dans un exemple d’application web Node.js à l’aide d’Azure AD B2C par votre propre application web Node.js.
Cet article utilise Node.js et Express pour créer une application web Node.js de base. Les vues de l’application utilisent Handlebars.
Prérequis
- Effectuez les étapes décrites dans Configurer l’authentification dans un exemple d’application web Node.js à l’aide d’Azure AD B2C. Vous allez créer des flux d’utilisateurs Azure AD B2C et inscrire une application web dans le Portail Azure.
Étape 1 : créer le projet Node
Créez un dossier pour héberger votre application Node, par exemple active-directory-b2c-msal-node-sign-in-sign-out-webapp
.
Dans votre terminal, accédez à un répertoire dans votre dossier d’application Node, par exemple
cd active-directory-b2c-msal-node-sign-in-sign-out-webapp
, et exécuteznpm init -y
. Cette commande crée un fichierpackage.json
par défaut pour votre projet Node.js.Dans votre terminal, exécutez
npm install express
. Cette commande installe le framework Express.Créez d’autres dossiers et fichiers pour obtenir la structure de projet suivante :
active-directory-b2c-msal-node-sign-in-sign-out-webapp/ ├── index.js └── package.json └── .env └── views/ └── layouts/ └── main.hbs └── signin.hbs
Le dossier views
contient des fichiers Handlebars pour l’interface utilisateur de l’application.
Étape 2 : installer les dépendances d’application
Dans votre terminal, installez les packages dotenv
, express-handlebars
, express-session
et @azure/msal-node
en exécutant les commandes suivantes :
npm install dotenv
npm install express-handlebars
npm install express-session
npm install @azure/msal-node
Étape 3 : générer les composants de l’interface utilisateur de l’application
Dans le fichier main.hbs
, ajoutez le code suivant :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Tutorial | Authenticate users with MSAL for B2C</title>
<!-- adding Bootstrap 4 for UI components -->
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<a class="navbar-brand" href="/">Microsoft Identity Platform</a>
{{#if showSignInButton}}
<div class="ml-auto">
<a type="button" id="SignIn" class="btn btn-secondary" href="/signin" aria-haspopup="true" aria-expanded="false">
Sign in
</a>
</div>
{{else}}
<div class="ml-auto">
<a type="button" id="EditProfile" class="btn btn-warning" href="/profile" aria-haspopup="true" aria-expanded="false">
Edit profile
</a>
<a type="button" id="PasswordReset" class="btn btn-warning" href="/password" aria-haspopup="true" aria-expanded="false">
Reset password
</a>
</div>
<p class="navbar-brand d-flex ms-auto">Hi {{givenName}}</p>
<a class="navbar-brand d-flex ms-auto" href="/signout">Sign out</a>
{{/if}}
</nav>
<br>
<h5 class="card-header text-center">MSAL Node Confidential Client application with Auth Code Flow</h5>
<br>
<div class="row" style="margin:auto" >
{{{body}}}
</div>
<br>
<br>
</body>
</html>
Le fichier main.hbs
se trouve dans le dossier layout
. Il doit contenir tout code HTML requis dans votre application. Toute interface utilisateur passant d’une vue à une autre, comme dans signin.hbs
, est placée dans l’espace réservé indiqué sous la forme de {{{body}}}
.
Le fichier main.hbs
implémente l’interface utilisateur générée avec l’infrastructure CSS Bootstrap 5. Vous voyez les composants Modifier le mot de passe, Réinitialiser le mot de passe et Se déconnecter (boutons) de l’interface utilisateur quand vous êtes connecté. Vous voyez Se connecter lorsque vous êtes déconnecté. Ce comportement est contrôlé par la variable booléenne showSignInButton
que le serveur d’applications envoie.
Dans le fichier signin.hbs
, ajoutez le code suivant :
<div class="col-md-3" style="margin:auto">
<div class="card text-center">
<div class="card-body">
{{#if showSignInButton}}
<h5 class="card-title">Please sign-in to acquire an ID token</h5>
{{else}}
<h5 class="card-title">You have signed in</h5>
{{/if}}
</div>
<div class="card-body">
{{#if message}}
<h5 class="card-title text-danger">{{message}}</h5>
{{/if}}
</div>
</div>
</div>
Étape 4 : configurer le serveur web et le client MSAL
Dans le fichier
.env
, ajoutez le code suivant et mettez-le à jour comme indiqué dans Configurer l’exemple d’application web.#HTTP port SERVER_PORT=3000 #web apps client ID APP_CLIENT_ID=<You app client ID here> #session secret SESSION_SECRET=sessionSecretHere #web app client secret APP_CLIENT_SECRET=<Your app client secret here> #B2C sign up and sign in user flow/policy authority SIGN_UP_SIGN_IN_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<sign-in-sign-up-user-flow-name> #B2C password reset user flow/policy authority RESET_PASSWORD_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<reset-password-user-flow-name> #B2C edit profile user flow/policy authority EDIT_PROFILE_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<profile-edit-user-flow-name> #B2C authority domain AUTHORITY_DOMAIN=https://<your-tenant-name>.b2clogin.com #client redirect url APP_REDIRECT_URI=http://localhost:3000/redirect #Logout endpoint LOGOUT_ENDPOINT=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<sign-in-sign-up-user-flow-name>/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000
Dans votre fichier
index.js
, ajoutez le code suivant pour utiliser les dépendances de votre application :require('dotenv').config(); const express = require('express'); const session = require('express-session'); const {engine} = require('express-handlebars'); const msal = require('@azure/msal-node');
Dans votre fichier
index.js
, ajoutez le code suivant pour configurer la bibliothèque d’authentification :/** * Confidential Client Application Configuration */ const confidentialClientConfig = { auth: { clientId: process.env.APP_CLIENT_ID, authority: process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, clientSecret: process.env.APP_CLIENT_SECRET, knownAuthorities: [process.env.AUTHORITY_DOMAIN], //This must be an array redirectUri: process.env.APP_REDIRECT_URI, validateAuthority: false }, system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: false, logLevel: msal.LogLevel.Verbose, } } }; // Initialize MSAL Node const confidentialClientApplication = new msal.ConfidentialClientApplication(confidentialClientConfig);
confidentialClientConfig
est l’objet de configuration MSAL utilisé pour la connexion aux points de terminaison d’authentification de votre locataire Azure AD B2C.Pour ajouter des variables globales de mode dans le fichier
index.js
, ajoutez le code suivant :/** * The MSAL.js library allows you to pass your custom state as state parameter in the Request object * By default, MSAL.js passes a randomly generated unique state parameter value in the authentication requests. * The state parameter can also be used to encode information of the app's state before redirect. * You can pass the user's state in the app, such as the page or view they were on, as input to this parameter. * For more information, visit: https://docs.microsoft.com/azure/active-directory/develop/msal-js-pass-custom-state-authentication-request * In this scenario, the states also serve to show the action that was requested of B2C since only one redirect URL is possible. */ const APP_STATES = { LOGIN: 'login', LOGOUT: 'logout', PASSWORD_RESET: 'password_reset', EDIT_PROFILE : 'update_profile' } /** * Request Configuration * We manipulate these two request objects below * to acquire a token with the appropriate claims. */ const authCodeRequest = { redirectUri: confidentialClientConfig.auth.redirectUri, }; const tokenRequest = { redirectUri: confidentialClientConfig.auth.redirectUri, }; /** * Using express-session middleware. Be sure to familiarize yourself with available options * and set them as desired. Visit: https://www.npmjs.com/package/express-session */ const sessionConfig = { secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { secure: false, // set this to true on production } }
APP_STATES
: Permet de faire la distinction entre les réponses reçues de Azure AD B2C en marquant les demandes. Il n’existe qu’un seul URI de redirection pour un nombre quelconque de demandes envoyées à Azure AD B2C.authCodeRequest
: objet de configuration utilisé pour récupérer le code d’autorisation.tokenRequest
: objet de configuration utilisé pour acquérir un jeton par code d’autorisation.sessionConfig
: objet de configuration pour la session Express.
Pour définir le moteur de modèle d’affichage et la configuration de session Express, ajoutez le code suivant dans le fichier
index.js
://Create an express instance const app = express(); //Set handlebars as your view engine app.engine('.hbs', engine({extname: '.hbs'})); app.set('view engine', '.hbs'); app.set("views", "./views"); //usse session configuration app.use(session(sessionConfig));
Étape 5 : ajouter des itinéraires Express
Avant d’ajouter l’itinéraire de l’application, ajoutez la logique qui récupère l’URL du code d’autorisation, qui est la première partie du flux d’octroi du code d’autorisation. Dans le fichier index.js
, ajoutez le code suivant :
/**
* This method is used to generate an auth code request
* @param {string} authority: the authority to request the auth code from
* @param {array} scopes: scopes to request the auth code for
* @param {string} state: state of the application
* @param {Object} res: express middleware response object
*/
const getAuthCode = (authority, scopes, state, res) => {
// prepare the request
console.log("Fetching Authorization code")
authCodeRequest.authority = authority;
authCodeRequest.scopes = scopes;
authCodeRequest.state = state;
//Each time you fetch Authorization code, update the relevant authority in the tokenRequest configuration
tokenRequest.authority = authority;
// request an authorization code to exchange for a token
return confidentialClientApplication.getAuthCodeUrl(authCodeRequest)
.then((response) => {
console.log("\nAuthCodeURL: \n" + response);
//redirect to the auth code URL/send code to
res.redirect(response);
})
.catch((error) => {
res.status(500).send(error);
});
}
L’objet authCodeRequest
dispose des propriétés redirectUri
, authority
, scopes
et state
. L’objet est passé à la méthode getAuthCodeUrl
en tant que paramètre.
Dans le fichier index.js
, ajoutez le code suivant :
app.get('/', (req, res) => {
res.render('signin', { showSignInButton: true });
});
app.get('/signin',(req, res)=>{
//Initiate a Auth Code Flow >> for sign in
//no scopes passed. openid, profile and offline_access will be used by default.
getAuthCode(process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, [], APP_STATES.LOGIN, res);
});
/**
* Change password end point
*/
app.get('/password',(req, res)=>{
getAuthCode(process.env.RESET_PASSWORD_POLICY_AUTHORITY, [], APP_STATES.PASSWORD_RESET, res);
});
/**
* Edit profile end point
*/
app.get('/profile',(req, res)=>{
getAuthCode(process.env.EDIT_PROFILE_POLICY_AUTHORITY, [], APP_STATES.EDIT_PROFILE, res);
});
/**
* Sign out end point
*/
app.get('/signout',async (req, res)=>{
logoutUri = process.env.LOGOUT_ENDPOINT;
req.session.destroy(() => {
//When session destruction succeeds, notify B2C service using the logout uri.
res.redirect(logoutUri);
});
});
app.get('/redirect',(req, res)=>{
//determine the reason why the request was sent by checking the state
if (req.query.state === APP_STATES.LOGIN) {
//prepare the request for authentication
tokenRequest.code = req.query.code;
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\nAuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
console.log("\nErrorAtLogin: \n" + error);
});
}else if (req.query.state === APP_STATES.PASSWORD_RESET) {
//If the query string has a error param
if (req.query.error) {
//and if the error_description contains AADB2C90091 error code
//Means user selected the Cancel button on the password reset experience
if (JSON.stringify(req.query.error_description).includes('AADB2C90091')) {
//Send the user home with some message
//But always check if your session still exists
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name, message: 'User has cancelled the operation'});
}
}else{
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name});
}
}else if (req.query.state === APP_STATES.EDIT_PROFILE){
tokenRequest.scopes = [];
tokenRequest.code = req.query.code;
//Request token with claims, including the name that was updated.
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\AuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
//Handle error
});
}else{
res.status(500).send('We do not recognize this response!');
}
});
Les itinéraires Express sont les suivants :
/
:- Utilisé pour accéder à l’application web.
- Affiche la page
signin
.
/signin
:- Utilisé lorsque vous vous connectez.
- Appelle la méthode
getAuthCode()
et lui passeauthority
pour le flux ou la stratégie utilisateur Inscription et connexion,APP_STATES.LOGIN
, et un tableauscopes
vide. - Si nécessaire, vous devez entrer vos informations d’identification. Si vous n’avez pas de compte, vous êtes invité à vous inscrire.
- La réponse finale résultant de cet itinéraire comprend un code d’autorisation d’Azure AD B2C retourné à l’itinéraire
/redirect
.
/password
:- Utilisé lorsque vous réinitialisez un mot de passe.
- Appelle la méthode
getAuthCode()
et lui passeauthority
pour le flux ou la stratégie utilisateur Réinitialisation du mot de passe,APP_STATES.PASSWORD_RESET
, et un tableauscopes
vide. - Permet de modifier votre mot de passe à l’aide de l’expérience de réinitialisation du mot de passe, ou d’annuler l’opération.
- La réponse finale résultant de cet itinéraire comprend un code d’autorisation d’Azure AD B2C retourné à l’itinéraire
/redirect
. Si vous annulez l’opération, une erreur est retournée.
/profile
:- Utilisé lorsque vous mettez à jour votre profil.
- Appelle la méthode
getAuthCode()
et lui passeauthority
pour le flux ou la stratégie utilisateur Modification du profil,APP_STATES.EDIT_PROFILE
, et un tableauscopes
vide. - Permet de mettre à jour votre profil et d’utiliser l’expérience de modification de profil.
- La réponse finale résultant de cet itinéraire comprend un code d’autorisation d’Azure AD B2C retourné à l’itinéraire
/redirect
.
/signout
:- Utilisé lorsque vous vous déconnectez.
- L’application web efface la session et effectue un appel HTTP au point de terminaison de déconnexion d’Azure AD B2C.
/redirect
:- Itinéraire défini en tant qu’URI de redirection pour l’application web dans le Portail Azure.
- Utilise le paramètre de requête
state
dans la demande d’Azure AD B2C pour différencier les demandes effectuées à partir de l’application web. Gère toutes les redirections à partir d’Azure AD B2C, à l’exception de la déconnexion. - Si l’état de l’application est
APP_STATES.LOGIN
, le code d’autorisation acquis est utilisé pour récupérer un jeton via la méthodeacquireTokenByCode()
. Ce jeton inclutidToken
etidTokenClaims
, qui sont utilisés pour l’identification de l’utilisateur. - Si l’état de l’application est
APP_STATES.PASSWORD_RESET
, elle gère toutes les erreurs, telles queuser cancelled the operation
. Le code d’erreurAADB2C90091
identifie cette erreur. Dans le cas contraire, il décide de l’expérience utilisateur suivante. - Si l’état de l’application est
APP_STATES.EDIT_PROFILE
, il utilise le code d’autorisation pour acquérir un jeton. Le jeton contientidTokenClaims
, qui inclut les nouvelles modifications.
Étape 6 : démarrer le serveur Node
Pour démarrer le serveur Node, ajoutez le code suivant dans le fichier index.js
:
app.listen(process.env.SERVER_PORT, () => {
console.log(`Msal Node Auth Code Sample app listening on port !` + process.env.SERVER_PORT);
});
Une fois que vous avez apporté toutes les modifications requises dans le fichier index.js
, il doit ressembler à ce qui suit :
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
//<ms_docref_use_app_dependencies>
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const {engine} = require('express-handlebars');
const msal = require('@azure/msal-node');
//</ms_docref_use_app_dependencies>
//<ms_docref_configure_msal>
/**
* Confidential Client Application Configuration
*/
const confidentialClientConfig = {
auth: {
clientId: process.env.APP_CLIENT_ID,
authority: process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY,
clientSecret: process.env.APP_CLIENT_SECRET,
knownAuthorities: [process.env.AUTHORITY_DOMAIN], //This must be an array
redirectUri: process.env.APP_REDIRECT_URI,
validateAuthority: false
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
};
// Initialize MSAL Node
const confidentialClientApplication = new msal.ConfidentialClientApplication(confidentialClientConfig);
//</ms_docref_configure_msal>
//<ms_docref_global_variable>
/**
* The MSAL.js library allows you to pass your custom state as state parameter in the Request object
* By default, MSAL.js passes a randomly generated unique state parameter value in the authentication requests.
* The state parameter can also be used to encode information of the app's state before redirect.
* You can pass the user's state in the app, such as the page or view they were on, as input to this parameter.
* For more information, visit: https://docs.microsoft.com/azure/active-directory/develop/msal-js-pass-custom-state-authentication-request
* In this scenario, the states also serve to show the action that was requested of B2C since only one redirect URL is possible.
*/
const APP_STATES = {
LOGIN: 'login',
LOGOUT: 'logout',
PASSWORD_RESET: 'password_reset',
EDIT_PROFILE : 'update_profile'
}
/**
* Request Configuration
* We manipulate these two request objects below
* to acquire a token with the appropriate claims.
*/
const authCodeRequest = {
redirectUri: confidentialClientConfig.auth.redirectUri,
};
const tokenRequest = {
redirectUri: confidentialClientConfig.auth.redirectUri,
};
/**
* Using express-session middleware. Be sure to familiarize yourself with available options
* and set them as desired. Visit: https://www.npmjs.com/package/express-session
*/
const sessionConfig = {
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // set this to true on production
}
}
//</ms_docref_global_variable>
//<ms_docref_view_tepmplate_engine>
//Create an express instance
const app = express();
//Set handlebars as your view engine
app.engine('.hbs', engine({extname: '.hbs'}));
app.set('view engine', '.hbs');
app.set("views", "./views");
//usse session configuration
app.use(session(sessionConfig));
//</ms_docref_view_tepmplate_engine>
//<ms_docref_authorization_code_url>
/**
* This method is used to generate an auth code request
* @param {string} authority: the authority to request the auth code from
* @param {array} scopes: scopes to request the auth code for
* @param {string} state: state of the application
* @param {Object} res: express middleware response object
*/
const getAuthCode = (authority, scopes, state, res) => {
// prepare the request
console.log("Fetching Authorization code")
authCodeRequest.authority = authority;
authCodeRequest.scopes = scopes;
authCodeRequest.state = state;
//Each time you fetch Authorization code, update the relevant authority in the tokenRequest configuration
tokenRequest.authority = authority;
// request an authorization code to exchange for a token
return confidentialClientApplication.getAuthCodeUrl(authCodeRequest)
.then((response) => {
console.log("\nAuthCodeURL: \n" + response);
//redirect to the auth code URL/send code to
res.redirect(response);
})
.catch((error) => {
res.status(500).send(error);
});
}
//</ms_docref_authorization_code_url>
//<ms_docref_app_endpoints>
app.get('/', (req, res) => {
res.render('signin', { showSignInButton: true });
});
app.get('/signin',(req, res)=>{
//Initiate a Auth Code Flow >> for sign in
//no scopes passed. openid, profile and offline_access will be used by default.
getAuthCode(process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, [], APP_STATES.LOGIN, res);
});
/**
* Change password end point
*/
app.get('/password',(req, res)=>{
getAuthCode(process.env.RESET_PASSWORD_POLICY_AUTHORITY, [], APP_STATES.PASSWORD_RESET, res);
});
/**
* Edit profile end point
*/
app.get('/profile',(req, res)=>{
getAuthCode(process.env.EDIT_PROFILE_POLICY_AUTHORITY, [], APP_STATES.EDIT_PROFILE, res);
});
/**
* Sign out end point
*/
app.get('/signout',async (req, res)=>{
logoutUri = process.env.LOGOUT_ENDPOINT;
req.session.destroy(() => {
//When session destruction succeeds, notify B2C service using the logout uri.
res.redirect(logoutUri);
});
});
app.get('/redirect',(req, res)=>{
//determine the reason why the request was sent by checking the state
if (req.query.state === APP_STATES.LOGIN) {
//prepare the request for authentication
tokenRequest.code = req.query.code;
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\nAuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
console.log("\nErrorAtLogin: \n" + error);
});
}else if (req.query.state === APP_STATES.PASSWORD_RESET) {
//If the query string has a error param
if (req.query.error) {
//and if the error_description contains AADB2C90091 error code
//Means user selected the Cancel button on the password reset experience
if (JSON.stringify(req.query.error_description).includes('AADB2C90091')) {
//Send the user home with some message
//But always check if your session still exists
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name, message: 'User has cancelled the operation'});
}
}else{
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name});
}
}else if (req.query.state === APP_STATES.EDIT_PROFILE){
tokenRequest.scopes = [];
tokenRequest.code = req.query.code;
//Request token with claims, including the name that was updated.
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\AuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
//Handle error
});
}else{
res.status(500).send('We do not recognize this response!');
}
});
//</ms_docref_app_endpoints>
//start app server to listen on set port
//<ms_docref_start_node_server>
app.listen(process.env.SERVER_PORT, () => {
console.log(`Msal Node Auth Code Sample app listening on port !` + process.env.SERVER_PORT);
});
//</ms_docref_start_node_server>
Étape 7 : exécuter votre application web
Suivez les étapes de la section Exécuter votre application web pour tester votre application web Node.js.
Étapes suivantes
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour