Bagikan melalui


Tutorial: Memasukkan pengguna dan memperoleh token untuk Microsoft Graph di aplikasi web Node.js & Express

Dalam tutorial ini, Anda membuat aplikasi web yang memasukkan pengguna dan memperoleh token akses untuk memanggil Microsoft Graph. Aplikasi web yang Anda buat menggunakan Microsoft Authentication Library (MSAL) untuk Node.

Ikuti langkah-langkah dalam tutorial ini untuk:

  • Mendaftarkan aplikasi di portal Microsoft Azure
  • Membuat proyek aplikasi web Ekspres
  • Menginstal paket pustaka autentikasi
  • Menambahkan detail pendaftaran aplikasi
  • Menambahkan kode untuk login pengguna
  • Uji aplikasi Untuk informasi selengkapnya, lihat kode sampel yang menunjukkan cara menggunakan MSAL Node untuk masuk, keluar, dan memperoleh token akses untuk sumber daya yang dilindungi seperti Microsoft Graph.

Prasyarat

Mendaftarkan aplikasi

Pertama, selesaikan langkah-langkah dalam Mendaftarkan aplikasi dengan platform identitas Microsoft untuk mendaftarkan aplikasi Anda.

Gunakan pengaturan berikut untuk pendaftaran aplikasi Anda:

  • Nama: ExpressWebApp (disarankan)
  • Jenis akun yang didukung: Hanya akun dalam direktori organisasi ini
  • Jenis platform: Web
  • URI Pengalihan: http://localhost:3000/auth/redirect
  • Rahasia klien: ********* (catat nilai ini untuk digunakan di langkah selanjutnya - hanya ditampilkan sekali)

Membuat proyek

Gunakan alat generator aplikasi Express untuk membuat kerangka aplikasi.

  1. Pertama, instal paket generator ekspres :
    npm install -g express-generator
  1. Kemudian, buat kerangka aplikasi sebagai berikut:
    express --view=hbs /ExpressWebApp && cd /ExpressWebApp
    npm install

Anda sekarang memiliki aplikasi web Express sederhana. Struktur file dan folder proyek Anda akan terlihat mirip dengan struktur folder berikut:

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

Menginstal pustaka otorisasi

Temukan akar direktori proyek Anda di terminal dan instal paket MSAL Node melalui npm.

    npm install --save @azure/msal-node

Menginstal dependensi lain

Sampel aplikasi web dalam tutorial ini menggunakan paket sesi ekspres untuk manajemen sesi, paket dotenv untuk membaca parameter lingkungan selama pengembangan, dan axios untuk melakukan panggilan jaringan ke Microsoft Graph API. Instal ini melalui npm:

    npm install --save express-session dotenv axios

Menambahkan detail pendaftaran aplikasi

  1. Buat file .env.dev di akar folder proyek Anda. Kemudian tambahkan kode berikut:
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"

Isi detail ini dengan nilai yang Anda peroleh dari portal pendaftaran aplikasi Azure:

  • Enter_the_Cloud_Instance_Id_Here: Instans cloud Azure tempat aplikasi Anda terdaftar.
    • Untuk cloud Azure utama (atau global), masukkan https://login.microsoftonline.com/ (sertakan garis miring terakhir).
    • Untuk cloud nasional (misalnya, Tiongkok), Anda dapat menemukan nilai yang sesuai di cloud Nasional.
  • Enter_the_Tenant_Info_here harus menjadi salah satu parameter berikut:
    • Jika aplikasi Anda mendukung akun di direktori organisasi ini, ganti nilai ini dengan ID Penyewa atau Nama penyewa. Contohnya, contoso.microsoft.com.
    • Jika aplikasi Anda mendukung akun di direktori organisasi apa pun, ganti nilai ini dengan organizations.
    • Jika aplikasi Anda mendukung akun di direktori organisasi dan akun Microsoft pribadi apa pun, ganti nilai ini dengan common.
    • Untuk membatasi dukungan hanya untuk akun Microsoft pribadi, ganti nilai ini dengan consumers.
  • Enter_the_Application_Id_Here: ID Aplikasi (klien) aplikasi yang Anda daftarkan.
  • Enter_the_Client_secret: Ganti nilai ini dengan rahasia klien yang Anda buat sebelumnya. Untuk menghasilkan kunci baru, gunakan Sertifikat & rahasia di pengaturan pendaftaran aplikasi di portal Microsoft Azure.

Peringatan

Rahasia teks biasa apa pun dalam kode sumber menimbulkan peningkatan risiko keamanan. Artikel ini menggunakan rahasia klien teks biasa hanya untuk kesederhanaan. Gunakan kredensial sertifikat daripada rahasia klien di aplikasi klien rahasia Anda, terutama aplikasi yang ingin Anda sebarkan ke produksi.

  • Enter_the_Graph_Endpoint_Here: Instans cloud Microsoft Graph API yang akan dipanggil aplikasi Anda. Untuk layanan utama (global) Microsoft Graph API, masukkan https://graph.microsoft.com/ (sertakan garis miring di akhir).
  • Enter_the_Express_Session_Secret_Here rahasia yang digunakan untuk menandatangani cookie sesi Express. Pilih string karakter acak untuk mengganti string ini dengan, seperti rahasia klien Anda.
  1. Selanjutnya, buat file bernama authConfig.js di akar proyek Anda untuk dibaca dalam parameter ini. Setelah dibuat, tambahkan kode berikut di sana:
/*
 * 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
};

Menambahkan kode untuk masuk pengguna dan akuisisi token

  1. Buat folder baru bernama auth, dan tambahkan file baru bernama AuthProvider.js di bawahnya. Ini akan berisi kelas AuthProvider , yang merangkum logika autentikasi yang diperlukan menggunakan MSAL Node. Tambahkan kode berikut di sana:
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. Selanjutnya, buat file baru bernama auth.js di bawah folder rute dan tambahkan kode berikut di sana:
/*
 * 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. Perbarui rute index.js dengan mengganti kode yang ada dengan cuplikan kode berikut:
/*
 * 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. Terakhir, perbarui rute users.js dengan mengganti kode yang ada dengan cuplikan kode berikut:
/*
 * 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;

Menambahkan kode untuk memanggil Microsoft Graph API

Buat file bernama fetch.js di akar proyek Anda dan tambahkan kode berikut:

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

Menambahkan tampilan untuk menampilkan data

  1. Di folder tampilan , perbarui file index.hbs dengan mengganti kode yang ada dengan yang berikut ini:
<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. Masih di folder yang sama, buat file lain bernama id.hbs untuk menampilkan konten token ID pengguna:
<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. Terakhir, buat file lain bernama profile.hbs untuk menampilkan hasil panggilan yang dilakukan ke 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>

Mendaftarkan router dan menambahkan manajemen status

Dalam file app.js di akar folder proyek, daftarkan rute yang telah Anda buat sebelumnya dan tambahkan dukungan sesi untuk melacak status autentikasi menggunakan paket sesi ekspres . Ganti kode yang ada di sana dengan cuplikan kode berikut:

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

Menguji masuk dan memanggil Microsoft Graph

Anda telah menyelesaikan pembuatan aplikasi dan sekarang siap untuk menguji fungsionalitas aplikasi.

  1. Mulai aplikasi konsol Node.js dengan menjalankan perintah berikut dari dalam akar folder proyek Anda:
   npm start
  1. Buka jendela browser dan navigasi ke http://localhost:3000. Anda akan melihat halaman selamat datang:

Halaman selamat datang aplikasi web yang ditampilkan

  1. Pilih tautan Masuk . Anda akan melihat layar masuk Microsoft Entra:

Layar masuk Microsoft Entra yang ditampilkan

  1. Setelah memasukkan kredensial, Anda akan melihat layar persetujuan yang meminta Anda untuk menyetujui izin untuk aplikasi.

Layar persetujuan Microsoft Entra yang ditampilkan

  1. Setelah menyetujui, Anda harus diarahkan kembali ke beranda aplikasi.

Halaman selamat datang aplikasi web setelah masuk ditampilkan

  1. Pilih tautan Lihat Token ID untuk menampilkan konten token ID pengguna yang masuk.

Layar token ID pengguna yang ditampilkan

  1. Kembali ke beranda, dan pilih tautan Dapatkan token akses dan panggil Microsoft Graph API . Setelah Anda melakukannya, Anda akan melihat respons dari endpoint Microsoft Graph /me untuk pengguna yang telah masuk.

Layar panggilan grafik sedang ditampilkan

  1. Kembali ke halaman beranda, dan pilih tautan Keluar . Anda akan melihat layar keluar Microsoft Entra.

Layar keluar Microsoft Entra sedang ditampilkan

Cara kerja aplikasi

Dalam tutorial ini, Anda membuat instans objek MSAL Node ConfidentialClientApplication dengan meneruskannya objek konfigurasi (msalConfig) yang berisi parameter yang diperoleh dari pendaftaran aplikasi Microsoft Entra Anda di portal Microsoft Azure. Aplikasi web yang Anda buat menggunakan protokol OpenID Connect untuk memasukkan pengguna dan alur kode otorisasi OAuth 2.0 untuk mendapatkan token akses.

Langkah berikutnya

Jika Anda ingin mendalami pengembangan aplikasi web Node.js & Express di platform identitas Microsoft, lihat seri skenario multi-bagian kami: