Tutoriel : connecter des utilisateurs et acquérir un jeton pour Microsoft Graph dans une application web Node.js & Express

Dans ce tutoriel, vous créez une application web qui connecte les utilisateurs et acquiert des jetons d’accès pour appeler Microsoft Graph. L’application web que vous créez utilise la bibliothèque d’authentification Microsoft (MSAL) pour Node.

Suivez les étapes de ce tutoriel pour :

  • Inscrire l’application dans le Portail Azure
  • Créer un projet d’application web Express
  • Installer les packages de la bibliothèque d’authentification
  • Ajouter les détails de l’inscription de l’application
  • Ajouter le code pour la connexion des utilisateurs
  • Test de l'application

Pour plus d’informations, reportez-vous à l’exemple de code qui montre comment utiliser MSAL Node pour se connecter, se déconnecter et acquérir un jeton d’accès pour une ressource protégée telle que Microsoft Graph.

Prérequis

Enregistrement de l’application

Effectuez d’abord les étapes décrites dans Inscrire une application auprès de la plateforme d’identités Microsoft pour enregistrer votre application.

Utilisez les paramètres suivants pour l’inscription de votre application :

  • Nom : ExpressWebApp (suggéré)
  • Types de comptes pris en charge : Comptes dans cet annuaire organisationnel uniquement
  • Type de plateforme : Web
  • URI de redirection : http://localhost:3000/auth/redirect
  • Secret client : ********* (enregistrez cette valeur pour l’utiliser à une étape ultérieure ; elle n’est affichée qu’une seule fois)

Créer le projet

Utilisez l’outil générateur d’applications Express pour créer un squelette d’application.

  1. Tout d’abord, installez le package express-generator :
    npm install -g express-generator
  1. Ensuite, créez un squelette d’application comme suit :
    express --view=hbs /ExpressWebApp && cd /ExpressWebApp
    npm install

Vous disposez maintenant d’une application web Express simple. La structure des fichiers et des dossiers de votre projet doit ressembler à la structure de fichier suivante :

ExpressWebApp/
├── bin/
|    └── wwww
├── public/
|    ├── images/
|    ├── javascript/
|    └── stylesheets/
|        └── style.css
├── routes/
|    ├── index.js
|    └── users.js
├── views/
|    ├── error.hbs
|    ├── index.hbs
|    └── layout.hbs
├── app.js
└── package.json

Installer la bibliothèque d’authentification

Localisez la racine du répertoire de votre projet dans un terminal et installez le package MSAL Node via npm.

    npm install --save @azure/msal-node

Installer d’autres dépendances

L’exemple d’application web de ce tutoriel utilise le package express-session pour la gestion des sessions, le package dotenv pour lire les paramètres d’environnement pendant le développement et axios pour passer les appels réseau à Microsoft API Graph. Installez-les via npm :

    npm install --save express-session dotenv axios

Ajouter les détails de l’inscription de l’application

  1. Créez un fichier .env.dev à la racine du dossier de votre projet. Ensuite, ajoutez le code suivant :
CLOUD_INSTANCE="Enter_the_Cloud_Instance_Id_Here" # cloud instance string should end with a trailing slash
TENANT_ID="Enter_the_Tenant_Info_Here"
CLIENT_ID="Enter_the_Application_Id_Here"
CLIENT_SECRET="Enter_the_Client_Secret_Here"

REDIRECT_URI="http://localhost:3000/auth/redirect"
POST_LOGOUT_REDIRECT_URI="http://localhost:3000"

GRAPH_API_ENDPOINT="Enter_the_Graph_Endpoint_Here" # graph api endpoint string should end with a trailing slash

EXPRESS_SESSION_SECRET="Enter_the_Express_Session_Secret_Here"

Utilisez les valeurs que vous obtenez du portail d’inscription des applications Azure pour renseigner ces détails :

  • Enter_the_Cloud_Instance_Id_Here: instance cloud Azure dans laquelle votre application est inscrite.
    • Pour le cloud Azure principal (ou global), entrez (incluez https://login.microsoftonline.com/ la barre oblique de fin).
    • Pour les clouds nationaux (par exemple la Chine), vous trouverez les valeurs appropriées dans Clouds nationaux.
  • Enter_the_Tenant_Info_here doit prendre l’un des paramètres suivants :
    • Si votre application prend en charge les comptes dans cet annuaire organisationnel, remplacez cette valeur par l’ID de locataire ou le Nom du locataire. Par exemple : contoso.microsoft.com.
    • Si votre application prend en charge les comptes dans un annuaire organisationnel, remplacez cette valeur par organizations.
    • Si votre application prend en charge les comptes dans un annuaire organisationnel et comptes personnels Microsoft, remplacez cette valeur par common.
    • Pour limiter la prise en charge aux comptes Microsoft personnels uniquement, remplacez cette valeur par consumers.
  • Enter_the_Application_Id_Here: ID d’application (client) de l’application que vous avez inscrite.
  • Enter_the_Client_secret : Remplacez cette valeur par le secret client que vous avez créé précédemment. Pour générer une nouvelle clé, utilisez Certificats et secrets dans les paramètres d’inscription de l’application dans le portail Azure.

Avertissement

Tout secret en texte clair dans le code source présente un risque accru pour la sécurité. Cet article utilise un secret client en texte clair uniquement pour rester simple. Utilisez des informations d’identification de certificat plutôt que des secrets client dans vos applications clientes confidentielles, en particulier dans celles que vous prévoyez de déployer en production.

  • Enter_the_Graph_Endpoint_Here : instance cloud Microsoft API Graph que votre application appellera. Pour le service API Microsoft Graph principal (mondial), entrez https://graph.microsoft.com/ (en incluant la barre oblique de fin).
  • Enter_the_Express_Session_Secret_Here : secret utilisé pour signer le cookie de session Express. Choisissez une chaîne aléatoire de caractères pour remplacer cette chaîne, par exemple votre clé secrète client.
  1. Ensuite, créez un fichier nommé authConfig.js à la racine de votre projet pour la lecture des paramètres. Une fois qu’il est créé, ajoutez-y le code suivant :
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

require('dotenv').config({ path: '.env.dev' });

/**
 * Configuration object to be passed to MSAL instance on creation.
 * For a full list of MSAL Node configuration parameters, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md
 */
const msalConfig = {
    auth: {
        clientId: process.env.CLIENT_ID, // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
        authority: process.env.CLOUD_INSTANCE + process.env.TENANT_ID, // Full directory URL, in the form of https://login.microsoftonline.com/<tenant>
        clientSecret: process.env.CLIENT_SECRET // Client secret generated from the app registration in Azure portal
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: 3,
        }
    }
}

const REDIRECT_URI = process.env.REDIRECT_URI;
const POST_LOGOUT_REDIRECT_URI = process.env.POST_LOGOUT_REDIRECT_URI;
const GRAPH_ME_ENDPOINT = process.env.GRAPH_API_ENDPOINT + "v1.0/me";

module.exports = {
    msalConfig,
    REDIRECT_URI,
    POST_LOGOUT_REDIRECT_URI,
    GRAPH_ME_ENDPOINT
};

Ajouter du code pour l’acquisition de jetons et de connexion utilisateur

  1. Créez un dossier nommé auth et ajoutez-y un nouveau fichier nommé AuthProvider.js. Il contient la classe AuthProvider qui encapsule la logique d’authentification nécessaire au moyen du nœud MSAL. Ajoutez-y le code suivant :
const msal = require('@azure/msal-node');
const axios = require('axios');

const { msalConfig } = require('../authConfig');

class AuthProvider {
    msalConfig;
    cryptoProvider;

    constructor(msalConfig) {
        this.msalConfig = msalConfig
        this.cryptoProvider = new msal.CryptoProvider();
    };

    login(options = {}) {
        return async (req, res, next) => {

            /**
             * MSAL Node library allows you to pass your custom state as state parameter in the Request object.
             * 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.
             */
            const state = this.cryptoProvider.base64Encode(
                JSON.stringify({
                    successRedirect: options.successRedirect || '/',
                })
            );

            const authCodeUrlRequestParams = {
                state: state,

                /**
                 * By default, MSAL Node will add OIDC scopes to the auth code url request. For more information, visit:
                 * https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
                 */
                scopes: options.scopes || [],
                redirectUri: options.redirectUri,
            };

            const authCodeRequestParams = {
                state: state,

                /**
                 * By default, MSAL Node will add OIDC scopes to the auth code request. For more information, visit:
                 * https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
                 */
                scopes: options.scopes || [],
                redirectUri: options.redirectUri,
            };

            /**
             * If the current msal configuration does not have cloudDiscoveryMetadata or authorityMetadata, we will 
             * make a request to the relevant endpoints to retrieve the metadata. This allows MSAL to avoid making 
             * metadata discovery calls, thereby improving performance of token acquisition process. For more, see:
             * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/performance.md
             */
            if (!this.msalConfig.auth.cloudDiscoveryMetadata || !this.msalConfig.auth.authorityMetadata) {

                const [cloudDiscoveryMetadata, authorityMetadata] = await Promise.all([
                    this.getCloudDiscoveryMetadata(this.msalConfig.auth.authority),
                    this.getAuthorityMetadata(this.msalConfig.auth.authority)
                ]);

                this.msalConfig.auth.cloudDiscoveryMetadata = JSON.stringify(cloudDiscoveryMetadata);
                this.msalConfig.auth.authorityMetadata = JSON.stringify(authorityMetadata);
            }

            const msalInstance = this.getMsalInstance(this.msalConfig);

            // trigger the first leg of auth code flow
            return this.redirectToAuthCodeUrl(
                authCodeUrlRequestParams,
                authCodeRequestParams,
                msalInstance
            )(req, res, next);
        };
    }

    acquireToken(options = {}) {
        return async (req, res, next) => {
            try {
                const msalInstance = this.getMsalInstance(this.msalConfig);

                /**
                 * If a token cache exists in the session, deserialize it and set it as the 
                 * cache for the new MSAL CCA instance. For more, see: 
                 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/caching.md
                 */
                if (req.session.tokenCache) {
                    msalInstance.getTokenCache().deserialize(req.session.tokenCache);
                }

                const tokenResponse = await msalInstance.acquireTokenSilent({
                    account: req.session.account,
                    scopes: options.scopes || [],
                });

                /**
                 * On successful token acquisition, write the updated token 
                 * cache back to the session. For more, see: 
                 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/caching.md
                 */
                req.session.tokenCache = msalInstance.getTokenCache().serialize();
                req.session.accessToken = tokenResponse.accessToken;
                req.session.idToken = tokenResponse.idToken;
                req.session.account = tokenResponse.account;

                res.redirect(options.successRedirect);
            } catch (error) {
                if (error instanceof msal.InteractionRequiredAuthError) {
                    return this.login({
                        scopes: options.scopes || [],
                        redirectUri: options.redirectUri,
                        successRedirect: options.successRedirect || '/',
                    })(req, res, next);
                }

                next(error);
            }
        };
    }

    handleRedirect(options = {}) {
        return async (req, res, next) => {
            if (!req.body || !req.body.state) {
                return next(new Error('Error: response not found'));
            }

            const authCodeRequest = {
                ...req.session.authCodeRequest,
                code: req.body.code,
                codeVerifier: req.session.pkceCodes.verifier,
            };

            try {
                const msalInstance = this.getMsalInstance(this.msalConfig);

                if (req.session.tokenCache) {
                    msalInstance.getTokenCache().deserialize(req.session.tokenCache);
                }

                const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body);

                req.session.tokenCache = msalInstance.getTokenCache().serialize();
                req.session.idToken = tokenResponse.idToken;
                req.session.account = tokenResponse.account;
                req.session.isAuthenticated = true;

                const state = JSON.parse(this.cryptoProvider.base64Decode(req.body.state));
                res.redirect(state.successRedirect);
            } catch (error) {
                next(error);
            }
        }
    }

    logout(options = {}) {
        return (req, res, next) => {

            /**
             * Construct a logout URI and redirect the user to end the
             * session with Azure AD. For more information, visit:
             * https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc#send-a-sign-out-request
             */
            let logoutUri = `${this.msalConfig.auth.authority}/oauth2/v2.0/`;

            if (options.postLogoutRedirectUri) {
                logoutUri += `logout?post_logout_redirect_uri=${options.postLogoutRedirectUri}`;
            }

            req.session.destroy(() => {
                res.redirect(logoutUri);
            });
        }
    }

    /**
     * Instantiates a new MSAL ConfidentialClientApplication object
     * @param msalConfig: MSAL Node Configuration object 
     * @returns 
     */
    getMsalInstance(msalConfig) {
        return new msal.ConfidentialClientApplication(msalConfig);
    }


    /**
     * Prepares the auth code request parameters and initiates the first leg of auth code flow
     * @param req: Express request object
     * @param res: Express response object
     * @param next: Express next function
     * @param authCodeUrlRequestParams: parameters for requesting an auth code url
     * @param authCodeRequestParams: parameters for requesting tokens using auth code
     */
    redirectToAuthCodeUrl(authCodeUrlRequestParams, authCodeRequestParams, msalInstance) {
        return async (req, res, next) => {
            // Generate PKCE Codes before starting the authorization flow
            const { verifier, challenge } = await this.cryptoProvider.generatePkceCodes();

            // Set generated PKCE codes and method as session vars
            req.session.pkceCodes = {
                challengeMethod: 'S256',
                verifier: verifier,
                challenge: challenge,
            };

            /**
             * By manipulating the request objects below before each request, we can obtain
             * auth artifacts with desired claims. For more information, visit:
             * https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationurlrequest
             * https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationcoderequest
             **/
            req.session.authCodeUrlRequest = {
                ...authCodeUrlRequestParams,
                responseMode: msal.ResponseMode.FORM_POST, // recommended for confidential clients
                codeChallenge: req.session.pkceCodes.challenge,
                codeChallengeMethod: req.session.pkceCodes.challengeMethod,
            };

            req.session.authCodeRequest = {
                ...authCodeRequestParams,
                code: '',
            };

            try {
                const authCodeUrlResponse = await msalInstance.getAuthCodeUrl(req.session.authCodeUrlRequest);
                res.redirect(authCodeUrlResponse);
            } catch (error) {
                next(error);
            }
        };
    }

    /**
     * Retrieves cloud discovery metadata from the /discovery/instance endpoint
     * @returns 
     */
    async getCloudDiscoveryMetadata(authority) {
        const endpoint = 'https://login.microsoftonline.com/common/discovery/instance';

        try {
            const response = await axios.get(endpoint, {
                params: {
                    'api-version': '1.1',
                    'authorization_endpoint': `${authority}/oauth2/v2.0/authorize`
                }
            });

            return await response.data;
        } catch (error) {
            throw error;
        }
    }

    /**
     * Retrieves oidc metadata from the openid endpoint
     * @returns
     */
    async getAuthorityMetadata(authority) {
        const endpoint = `${authority}/v2.0/.well-known/openid-configuration`;

        try {
            const response = await axios.get(endpoint);
            return await response.data;
        } catch (error) {
            console.log(error);
        }
    }
}

const authProvider = new AuthProvider(msalConfig);

module.exports = authProvider;
  1. Créez ensuite un fichier nommé auth.js dans le dossier itinéraires et ajoutez le code suivant :
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

var express = require('express');

const authProvider = require('../auth/AuthProvider');
const { REDIRECT_URI, POST_LOGOUT_REDIRECT_URI } = require('../authConfig');

const router = express.Router();

router.get('/signin', authProvider.login({
    scopes: [],
    redirectUri: REDIRECT_URI,
    successRedirect: '/'
}));

router.get('/acquireToken', authProvider.acquireToken({
    scopes: ['User.Read'],
    redirectUri: REDIRECT_URI,
    successRedirect: '/users/profile'
}));

router.post('/redirect', authProvider.handleRedirect());

router.get('/signout', authProvider.logout({
    postLogoutRedirectUri: POST_LOGOUT_REDIRECT_URI
}));

module.exports = router;
  1. Mettez à jour l’itinéraire index.js en remplaçant le code existant par l’extrait de code suivant :
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

var express = require('express');
var router = express.Router();

router.get('/', function (req, res, next) {
    res.render('index', {
        title: 'MSAL Node & Express Web App',
        isAuthenticated: req.session.isAuthenticated,
        username: req.session.account?.username,
    });
});

module.exports = router;
  1. Enfin, mettez à jour l’itinéraire users.js en remplaçant le code existant par l’extrait de code suivant :
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

var express = require('express');
var router = express.Router();

var fetch = require('../fetch');

var { GRAPH_ME_ENDPOINT } = require('../authConfig');

// custom middleware to check auth state
function isAuthenticated(req, res, next) {
    if (!req.session.isAuthenticated) {
        return res.redirect('/auth/signin'); // redirect to sign-in route
    }

    next();
};

router.get('/id',
    isAuthenticated, // check if user is authenticated
    async function (req, res, next) {
        res.render('id', { idTokenClaims: req.session.account.idTokenClaims });
    }
);

router.get('/profile',
    isAuthenticated, // check if user is authenticated
    async function (req, res, next) {
        try {
            const graphResponse = await fetch(GRAPH_ME_ENDPOINT, req.session.accessToken);
            res.render('profile', { profile: graphResponse });
        } catch (error) {
            next(error);
        }
    }
);

module.exports = router;

Ajouter du code pour appeler l’API Microsoft Graph

Créez un fichier nommé fetch.js à la racine de votre projet et ajoutez le code suivant :

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

var axios = require('axios');

/**
 * Attaches a given access token to a MS Graph API call
 * @param endpoint: REST API endpoint to call
 * @param accessToken: raw access token string
 */
async function fetch(endpoint, accessToken) {
    const options = {
        headers: {
            Authorization: `Bearer ${accessToken}`
        }
    };

    console.log(`request made to ${endpoint} at: ` + new Date().toString());

    try {
        const response = await axios.get(endpoint, options);
        return await response.data;
    } catch (error) {
        throw new Error(error);
    }
}

module.exports = fetch;

Ajouter des vues pour l’affichage des données

  1. Dans le dossier Vues, mettez à jour le fichier index.hbs en remplaçant le code existant par ce qui suit :
<h1>{{title}}</h1>
{{#if isAuthenticated }}
<p>Hi {{username}}!</p>
<a href="/users/id">View ID token claims</a>
<br>
<a href="/auth/acquireToken">Acquire a token to call the Microsoft Graph API</a>
<br>
<a href="/auth/signout">Sign out</a>
{{else}}
<p>Welcome to {{title}}</p>
<a href="/auth/signin">Sign in</a>
{{/if}}
  1. Toujours dans le même dossier, créez un autre fichier nommé id.hbs pour afficher le contenu du jeton d’ID de l’utilisateur :
<h1>Azure AD</h1>
<h3>ID Token</h3>
<table>
    <tbody>
        {{#each idTokenClaims}}
        <tr>
            <td>{{@key}}</td>
            <td>{{this}}</td>
        </tr>
        {{/each}}
    </tbody>
</table>
<br>
<a href="https://aka.ms/id-tokens" target="_blank">Learn about claims in this ID token</a>
<br>
<a href="/">Go back</a>
  1. Enfin, créez un autre fichier nommé profile.hbs pour afficher le résultat de l’appel à Microsoft Graph :
<h1>Microsoft Graph API</h1>
<h3>/me endpoint response</h3>
<table>
    <tbody>
        {{#each profile}}
        <tr>
            <td>{{@key}}</td>
            <td>{{this}}</td>
        </tr>
        {{/each}}
    </tbody>
</table>
<br>
<a href="/">Go back</a>

Inscrire des routeurs et ajouter la gestion de l’état

Dans le fichier app.js à la racine du dossier projet, inscrivez les itinéraires que vous avez créés précédemment et ajoutez la prise en charge de la session pour le suivi de l’état d’authentification à l’aide du package express-session. Remplacez le code existant par l’extrait de code suivant :

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

require('dotenv').config();

var path = require('path');
var express = require('express');
var session = require('express-session');
var createError = require('http-errors');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var authRouter = require('./routes/auth');

// initialize express
var app = express();

/**
 * Using express-session middleware for persistent user session. Be sure to
 * familiarize yourself with available options. Visit: https://www.npmjs.com/package/express-session
 */
 app.use(session({
    secret: process.env.EXPRESS_SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        secure: false, // set this to true on production
    }
}));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

app.use(logger('dev'));
app.use(express.json());
app.use(cookieParser());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/auth', authRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;

Tester la connexion et appeler Microsoft Graph

Vous avez terminé la création de l’application, et êtes maintenant prêt à tester les fonctionnalités de l’application.

  1. Démarrez l’application console Node.js en exécutant la commande suivante à la racine du dossier de votre projet :
   npm start
  1. Ouvrez une fenêtre de navigateur et accédez à http://localhost:3000. Une page d’accueil doit s’ouvrir :

Web app welcome page displaying

  1. Sélectionnez le lien de connexion. Vous devriez voir l’écran de connexion à Microsoft Entra :

Microsoft Entra sign-in screen displaying

  1. Une fois vos informations d’identification entrées, un écran de consentement devrait s’afficher pour vous demander d’approuver les autorisations se rapportant à l’application.

Microsoft Entra consent screen displaying

  1. Une fois que vous avez donné votre consentement, vous devez être redirigé vers la page d’accueil de l’application.

Web app welcome page after sign-in displaying

  1. Sélectionnez le lien Afficher le jeton d’ID pour afficher le contenu du jeton d’ID connecté de l’utilisateur.

User ID token screen displaying

  1. Retour à la page d’accueil, puis sélectionnez Acquisition d’un jeton d’accès et appel du lien Microsoft API Graph. Une fois que ceci est fait, vous devez voir la réponse de Microsoft Graph point de terminaison /me pour l’utilisateur connecté.

Graph call screen displaying

  1. Revenez à la page d’accueil, puis sélectionnez le lien de déconnexion. Vous devriez voir l’écran de déconnexion de Microsoft Entra.

Microsoft Entra sign-out screen displaying

Fonctionnement de l’application

Dans ce tutoriel, vous avez créé une instance d’un objet ConfidentialClientApplication MSAL Node en lui transmettant un objet de configuration (msalConfig) qui contient les paramètres obtenus via l’inscription de votre application Microsoft Entra sur le portail Azure. L’application web que vous avez créée utilise le protocole de connexion OpenID pour connecter les utilisateurs et le flux d’octroi du code d’autorisation OAuth 2.0 pour obtenir les jetons d’accès.

Étapes suivantes

Si vous souhaitez approfondir le développement d’applications web Node.js & Express sur la plateforme d’identités Microsoft, consultez notre série de scénarios en plusieurs parties :