Udostępnij za pośrednictwem


Samouczek: logowanie użytkowników i uzyskiwanie tokenu dla programu Microsoft Graph w aplikacji internetowej Node.js & Express

W tym samouczku utworzysz aplikację webową, która umożliwia logowanie się użytkowników i uzyskuje tokeny dostępu do pracy z Microsoft Graph. Utworzona aplikacja internetowa używa biblioteki Microsoft Authentication Library (MSAL) dla środowiska Node.

Wykonaj kroki opisane w tym samouczku, aby:

  • Rejestrowanie aplikacji w witrynie Azure Portal
  • Tworzenie projektu aplikacji internetowej Express
  • Instalowanie pakietów biblioteki uwierzytelniania
  • Dodawanie szczegółów rejestracji aplikacji
  • Dodawanie kodu logowania użytkownika
  • Testowanie aplikacji

Aby uzyskać więcej informacji, zobacz przykładowy kod , który pokazuje, jak używać środowiska MSAL Node do logowania, wylogować się i uzyskać token dostępu dla chronionego zasobu, takiego jak Microsoft Graph.

Warunki wstępne

  • Node.js
  • programu Visual Studio Code lub innego edytora kodu

Rejestrowanie aplikacji

Najpierw wykonaj kroki opisane w Rejestrowanie aplikacji przy użyciu platformy tożsamości firmy Microsoft, aby zarejestrować aplikację.

Użyj następujących ustawień rejestracji aplikacji:

  • Nazwa: ExpressWebApp (sugerowane)
  • Obsługiwane typy kont: tylko konta w tym katalogu organizacyjnym
  • Typ platformy: Web
  • Identyfikator URI przekierowania: http://localhost:3000/auth/redirect
  • Klucz tajny klienta: ********* (zapisz tę wartość do użycia w późniejszym kroku — jest wyświetlana tylko raz)

Tworzenie projektu

Użyj narzędzia generatora aplikacji Express, aby utworzyć szkielet aplikacji.

  1. Najpierw zainstaluj pakiet express-generator.
    npm install -g express-generator
  1. Następnie utwórz szkielet aplikacji w następujący sposób:
    express --view=hbs /ExpressWebApp && cd /ExpressWebApp
    npm install

Masz teraz prostą aplikację internetową Express. Struktura plików i folderów projektu powinna wyglądać podobnie do następującej struktury folderów:

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

Instalowanie biblioteki uwierzytelniania

Znajdź katalog główny katalogu projektu w terminalu i zainstaluj pakiet MSAL Node za pośrednictwem narzędzia npm.

    npm install --save @azure/msal-node

Instalowanie innych zależności

Przykład aplikacji internetowej w tym samouczku używa pakietu sesji ekspresowej na potrzeby zarządzania sesjami, pakietu dotenv do odczytywania parametrów środowiska podczas programowania oraz axios do wykonywania wywołań sieciowych do interfejsu API programu Microsoft Graph. Zainstaluj je za pomocą narzędzia npm:

    npm install --save express-session dotenv axios

Dodawanie szczegółów rejestracji aplikacji

  1. Utwórz plik .env.dev w katalogu głównym folderu projektu. Następnie dodaj następujący kod:
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"

Wypełnij te szczegóły wartościami uzyskanymi w portalu rejestracji aplikacji platformy Azure:

  • Enter_the_Cloud_Instance_Id_Here: wystąpienie chmury platformy Azure, w którym zarejestrowano aplikację.
    • Dla głównej (lub globalnej) chmury Azure wprowadź https://login.microsoftonline.com/ (pamiętaj o końcowym ukośniku).
    • W przypadku chmur krajowych (na przykład w Chinach) można znaleźć odpowiednie wartości w chmurach krajowych.
  • Enter_the_Tenant_Info_here powinien być jednym z następujących parametrów:
    • Jeśli aplikacja obsługuje konta w tym katalogu organizacyjnym, zastąp tę wartość wartością identyfikatorem dzierżawy lub nazwą dzierżawy . Na przykład contoso.microsoft.com.
    • Jeśli aplikacja obsługuje konta w dowolnym katalogu organizacyjnym, zastąp tę wartość organizations.
    • Jeśli aplikacja obsługuje konta w dowolnym katalogu organizacyjnym oraz personalnych kontach Microsoft, zastąp tę wartość common.
    • Aby ograniczyć obsługę do osobistych kont Microsoft tylko, zastąp tę wartość consumers.
  • Enter_the_Application_Id_Here: Identyfikator aplikacji (klienta) dla zarejestrowanej aplikacji.
  • Enter_the_Client_secret: zastąp tę wartość utworzonym wcześniej tajnym kluczem klienta. Aby wygenerować nowy klucz, użyj Certificates & secrets w ustawieniach rejestracji aplikacji w witrynie Azure Portal.

Ostrzeżenie

Każdy wpis tajny w postaci zwykłego tekstu w kodzie źródłowym stanowi zwiększone zagrożenie bezpieczeństwa. W tym artykule użyto tajnego klucza klienta w formie zwykłego tekstu dla uproszczenia. Użyj poświadczeń certyfikatu zamiast tajnych kluczy klienta w poufnych aplikacjach klienckich, szczególnie w aplikacjach, które zamierzasz wdrożyć w produkcji.

  • Enter_the_Graph_Endpoint_Here: instancja chmury interfejsu API Microsoft Graph, którą wywoła twoja aplikacja. W przypadku głównej (globalnej) usługi interfejsu API programu Microsoft Graph wprowadź https://graph.microsoft.com/ (uwzględnij końcowy ukośnik).
  • Enter_the_Express_Session_Secret_Here tajemnica użyta do podpisania ciasteczka sesji Express. Wybierz losowy ciąg znaków, który ma zastąpić ten ciąg, na przykład klucz tajny klienta.
  1. Następnie utwórz plik o nazwie authConfig.js w katalogu głównym projektu do odczytu w tych parametrach. Po utworzeniu dodaj tam następujący kod:
/*
 * 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
};

Dodawanie kodu na potrzeby logowania użytkownika i uzyskiwania tokenu

  1. Utwórz nowy folder o nazwie authi dodaj pod nim nowy plik o nazwie AuthProvider.js. Będzie ona zawierać klasę AuthProvider, która hermetyzuje niezbędną logikę uwierzytelniania przy użyciu węzła MSAL. Dodaj tam następujący kod:
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. Następnie utwórz nowy plik o nazwie auth.js w folderze routes i dodaj w nim następujący kod:
/*
 * 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. Zaktualizuj trasę index.js, zastępując istniejący kod następującym fragmentem kodu:
/*
 * 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. Na koniec zaktualizuj trasę users.js, zastępując istniejący kod następującym fragmentem kodu:
/*
 * 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;

Dodawanie kodu do wywoływania interfejsu API programu Microsoft Graph

Utwórz plik o nazwie fetch.js w katalogu głównym projektu i dodaj następujący kod:

/*
 * 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;

Dodawanie widoków do wyświetlania danych

  1. W folderze views zaktualizuj plik index.hbs, zastępując istniejący kod poniższym:
<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. Nadal w tym samym folderze utwórz inny plik o nazwie id.hbs w celu wyświetlenia zawartości tokenu identyfikatora użytkownika:
<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. Na koniec utwórz inny plik o nazwie profile.hbs w celu wyświetlenia wyniku wywołania do programu 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>

Rejestrowanie routerów i dodawanie zarządzania stanem

W pliku app.js w katalogu głównym folderu projektu zarejestruj utworzone wcześniej trasy i dodaj obsługę sesji umożliwiającą śledzenie stanu uwierzytelnienia przy użyciu pakietu express-session. Zastąp istniejący kod następującym fragmentem kodu:

/*
 * 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;

Testowanie logowania i wywoływanie programu Microsoft Graph

Ukończono tworzenie aplikacji i teraz możesz przystąpić do testowania funkcjonalności aplikacji.

  1. Uruchom aplikację konsolową Node.js, uruchamiając następujące polecenie z poziomu katalogu głównego folderu projektu:
   npm start
  1. Otwórz okno przeglądarki i przejdź do http://localhost:3000. Powinna zostać wyświetlona strona powitalna:

strona powitalna aplikacji internetowej wyświetlająca

  1. Wybierz link Zaloguj się. Powinien zostać wyświetlony ekran logowania microsoft Entra:

Microsoft Entra ekran logowania wyświetlający

  1. Po wprowadzeniu poświadczeń powinien pojawić się ekran zgody proszący o zatwierdzenie uprawnień dla aplikacji.

ekran zgody Microsoft Entra wyświetlający

  1. Po wyrażeniu zgody powinno nastąpić przekierowanie z powrotem do strony głównej aplikacji.

strona powitalna aplikacji internetowej po zalogowaniu się, wyświetlająca

  1. Wybierz link ID Token, aby wyświetlić zawartość tokenu identyfikatora zalogowanego użytkownika.

ekran tokenu identyfikatora użytkownika wyświetlający

  1. Wróć do strony głównej i wybierz link Uzyskaj token dostępu i wywołaj interfejs API programu Microsoft Graph. Gdy to zrobisz, powinna zostać wyświetlona odpowiedź z punktu końcowego programu Microsoft Graph /me dla zalogowanego użytkownika.

Ekran wywołania wykresu Graph przedstawiający

  1. Wróć do strony głównej i wybierz link Wyloguj się. Powinien zostać wyświetlony ekran wylogowania firmy Microsoft Entra.

ekran wylogowania firmy Microsoft wyświetlający

Jak działa aplikacja

W tym samouczku utworzono wystąpienie obiektu ConfidentialClientApplication węzła MSAL, przekazując go do obiektu konfiguracji (msalConfig), który zawiera parametry uzyskane z rejestracji aplikacji Microsoft Entra w witrynie Azure Portal. Utworzona aplikacja internetowa używa protokołu OpenID Connect do logowania użytkowników oraz przepływu kodu autoryzacji OAuth 2.0 w celu otrzymania tokenów dostępu.

Następne kroki

Jeśli chcesz dowiedzieć się więcej na temat tworzenia aplikacji internetowych Node.js & Express na platformie tożsamości firmy Microsoft, zobacz naszą wieloczęściową serię scenariuszy: