Självstudie: Logga in användare och anropa Microsoft Graph API från en JavaScript-ensidesapp (SPA) med hjälp av autentiseringskodflöde

I den här självstudien skapar du ett JavaScript-ensidesprogram (SPA) som loggar in användare och anropar Microsoft Graph med hjälp av auktoriseringskodflödet med PKCE. Det SPA som du skapar använder Microsoft Authentication Library (MSAL) för JavaScript v2.0.

I den här självstudien:

  • Utföra OAuth 2.0-auktoriseringskodflödet med PKCE
  • Logga in personliga Microsoft-konton samt arbets- och skolkonton
  • Hämta en åtkomsttoken
  • Anropa Microsoft Graph eller ditt eget API som kräver åtkomsttoken som hämtats från Microsofts identitetsplattform

MSAL.js 2.0 förbättras på MSAL.js 1.0 genom att stödja auktoriseringskodflödet i webbläsaren i stället för det implicita beviljandeflödet. MSAL.js 2.0 stöder INTE implicit flöde.

Förutsättningar

  • Node.js för att köra en lokal webbserver
  • Visual Studio Code eller någon annan kodredigerare

Så här fungerar självstudieappen

Diagram showing the authorization code flow in a single-page application

Programmet du skapar i den här självstudien gör det möjligt för ett JavaScript SPA att fråga Microsoft Graph API genom att hämta säkerhetstoken från Microsofts identitetsplattform. I det här scenariot, efter att en användare har loggat in, begärs en åtkomsttoken och läggs till i HTTP-begäranden i auktoriseringshuvudet. Tokenförvärv och förnyelse hanteras av Microsoft Authentication Library for JavaScript (MSAL.js).

I den här självstudien används MSAL.js, webbläsarpaketet Microsoft Authentication Library for JavaScript v2.0.

Hämta det färdiga kodexemplet

Du kan ladda ned den här självstudiekursens slutförda exempelprojekt i stället genom att klona lagringsplatsen ms-identity-javascript-v2 .

git clone https://github.com/Azure-Samples/ms-identity-javascript-v2.git

Om du vill köra det nedladdade projektet i din lokala utvecklingsmiljö börjar du med att skapa en localhost-server för ditt program enligt beskrivningen i steg 1 i skapa projektet. När du är klar kan du konfigurera kodexemplet genom att hoppa över till konfigurationssteget.

Om du vill fortsätta med självstudien och skapa programmet själv går du vidare till nästa avsnitt, Skapa projektet.

Skapa projektet

När du har Node.js installerat skapar du en mapp som värd för ditt program, till exempel msal-spa-tutorial.

Implementera sedan en liten Express-webbserver för att hantera din index.html-fil .

  1. Ändra först till projektkatalogen i terminalen och kör sedan följande npm kommandon:

    npm init -y
    npm install @azure/msal-browser
    npm install express
    npm install morgan
    npm install yargs
    
  2. Skapa sedan en fil med namnet server.js och lägg till följande kod:

    const express = require('express');
    const morgan = require('morgan');
    const path = require('path');
    
    const DEFAULT_PORT = process.env.PORT || 3000;
    
    // initialize express.
    const app = express();
    
    // Initialize variables.
    let port = DEFAULT_PORT;
    
    // Configure morgan module to log all requests.
    app.use(morgan('dev'));
    
    // Setup app folders.
    app.use(express.static('app'));
    
    // Set up a route for index.html
    app.get('*', (req, res) => {
        res.sendFile(path.join(__dirname + '/index.html'));
    });
    
    // Start the server.
    app.listen(port);
    console.log(`Listening on port ${port}...`);
    

Skapa SPA-användargränssnittet

  1. Skapa en appmapp i projektkatalogen och skapa en index.html fil för JavaScript SPA. Den här filen implementerar ett användargränssnitt som skapats med Bootstrap 4 Framework och importerar skriptfiler för konfiguration, autentisering och API-anrop.

    Lägg till följande kod i filen index.html :

    <!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>Microsoft identity platform</title>
      <link rel="SHORTCUT ICON" href="./favicon.svg" type="image/x-icon">
    
       <!-- msal.min.js can be used in the place of msal.js; included msal.js to make debug easy -->
      <script src="https://alcdn.msauth.net/browser/2.30.0/js/msal-browser.js"
        integrity="sha384-o4ufwq3oKqc7IoCcR08YtZXmgOljhTggRwxP2CLbSqeXGtitAxwYaUln/05nJjit"
        crossorigin="anonymous"></script>
      
      <!-- adding Bootstrap 4 for UI components  -->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" 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>
        <div class="btn-group ml-auto dropleft">
          <button type="button" id="SignIn" class="btn btn-secondary" onclick="signIn()">
            Sign In
          </button>
        </div>
      </nav>
      <br>
      <h5 class="card-header text-center">Vanilla JavaScript SPA calling MS Graph API with MSAL.js</h5>
      <br>
      <div class="row" style="margin:auto">
        <div id="card-div" class="col-md-3" style="display:none">
          <div class="card text-center">
            <div class="card-body">
              <h5 class="card-title" id="WelcomeMessage">Please sign-in to see your profile and read your mails</h5>
              <div id="profile-div"></div>
              <br>
              <br>
              <button class="btn btn-primary" id="seeProfile" onclick="seeProfile()">See Profile</button>
              <br>
              <br>
              <button class="btn btn-primary" id="readMail" onclick="readMail()">Read Mails</button>
            </div>
          </div>
        </div>
        <br>
        <br>
        <div class="col-md-4">
          <div class="list-group" id="list-tab" role="tablist">
          </div>
        </div>
        <div class="col-md-5">
          <div class="tab-content" id="nav-tabContent">
          </div>
        </div>
      </div>
      <br>
      <br>
    
      <!-- importing bootstrap.js and supporting js libraries -->
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>
    
      <!-- importing app scripts (load order is important) -->
      <script type="text/javascript" src="./authConfig.js"></script>
      <script type="text/javascript" src="./graphConfig.js"></script>
      <script type="text/javascript" src="./ui.js"></script>
    
      <!-- <script type="text/javascript" src="./authRedirect.js"></script>   -->
      <!-- uncomment the above line and comment the line below if you would like to use the redirect flow -->
      <script type="text/javascript" src="./authPopup.js"></script>
      <script type="text/javascript" src="./graph.js"></script>
    </body>
    
    </html>
    
  2. I appmappen skapar du sedan en fil med namnet ui.js och lägger till följande kod. Den här filen kommer att komma åt och uppdatera DOM-element.

    // Select DOM elements to work with
    const welcomeDiv = document.getElementById("WelcomeMessage");
    const signInButton = document.getElementById("SignIn");
    const cardDiv = document.getElementById("card-div");
    const mailButton = document.getElementById("readMail");
    const profileButton = document.getElementById("seeProfile");
    const profileDiv = document.getElementById("profile-div");
    
    function showWelcomeMessage(username) {
        // Reconfiguring DOM elements
        cardDiv.style.display = 'initial';
        welcomeDiv.innerHTML = `Welcome ${username}`;
        signInButton.setAttribute("onclick", "signOut();");
        signInButton.setAttribute('class', "btn btn-success")
        signInButton.innerHTML = "Sign Out";
    }
    
    function updateUI(data, endpoint) {
        console.log('Graph API responded at: ' + new Date().toString());
    
        if (endpoint === graphConfig.graphMeEndpoint) {
            profileDiv.innerHTML = ''
            const title = document.createElement('p');
            title.innerHTML = "<strong>Title: </strong>" + data.jobTitle;
            const email = document.createElement('p');
            email.innerHTML = "<strong>Mail: </strong>" + data.mail;
            const phone = document.createElement('p');
            phone.innerHTML = "<strong>Phone: </strong>" + data.businessPhones[0];
            const address = document.createElement('p');
            address.innerHTML = "<strong>Location: </strong>" + data.officeLocation;
            profileDiv.appendChild(title);
            profileDiv.appendChild(email);
            profileDiv.appendChild(phone);
            profileDiv.appendChild(address);
    
        } else if (endpoint === graphConfig.graphMailEndpoint) {
            if (!data.value) {
                alert("You do not have a mailbox!")
            } else if (data.value.length < 1) {
                alert("Your mailbox is empty!")
            } else {
                const tabContent = document.getElementById("nav-tabContent");
                const tabList = document.getElementById("list-tab");
                tabList.innerHTML = ''; // clear tabList at each readMail call
    
                data.value.map((d, i) => {
                    // Keeping it simple
                    if (i < 10) {
                        const listItem = document.createElement("a");
                        listItem.setAttribute("class", "list-group-item list-group-item-action")
                        listItem.setAttribute("id", "list" + i + "list")
                        listItem.setAttribute("data-toggle", "list")
                        listItem.setAttribute("href", "#list" + i)
                        listItem.setAttribute("role", "tab")
                        listItem.setAttribute("aria-controls", i)
                        listItem.innerHTML = d.subject;
                        tabList.appendChild(listItem)
    
                        const contentItem = document.createElement("div");
                        contentItem.setAttribute("class", "tab-pane fade")
                        contentItem.setAttribute("id", "list" + i)
                        contentItem.setAttribute("role", "tabpanel")
                        contentItem.setAttribute("aria-labelledby", "list" + i + "list")
                        contentItem.innerHTML = "<strong> from: " + d.from.emailAddress.address + "</strong><br><br>" + d.bodyPreview + "...";
                        tabContent.appendChild(contentItem);
                    }
                });
            }
        }
    }
    

Registrera ditt program

Följ stegen i ensidesprogram: Appregistrering för att skapa en appregistrering för ditt SPA.

I steget Omdirigerings-URI: MSAL.js 2.0 med autentiseringskod anger du http://localhost:3000, standardplatsen där den här självstudiekursens program körs.

Om du vill använda en annan port anger du http://localhost:<port>, där <port> är ditt önskade TCP-portnummer. Om du anger ett annat portnummer än 3000uppdaterar du även server.js med önskat portnummer.

Konfigurera JavaScript SPA

Skapa en fil med namnet authConfig.js i appmappen för att innehålla konfigurationsparametrarna för autentisering och lägg sedan till följande kod:

/**
 * Configuration object to be passed to MSAL instance on creation. 
 * For a full list of MSAL.js configuration parameters, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md 
 */
const msalConfig = {
    auth: {
        // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
        clientId: "Enter_the_Application_Id_Here",
        // Full directory URL, in the form of https://login.microsoftonline.com/<tenant-id>
        authority: "Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here",
        // Full redirect URL, in form of http://localhost:3000
        redirectUri: "Enter_the_Redirect_Uri_Here",
    },
    cache: {
        cacheLocation: "sessionStorage", // This configures where your cache will be stored
        storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
    },
    system: {	
        loggerOptions: {	
            loggerCallback: (level, message, containsPii) => {	
                if (containsPii) {		
                    return;		
                }		
                switch (level) {		
                    case msal.LogLevel.Error:		
                        console.error(message);		
                        return;		
                    case msal.LogLevel.Info:		
                        console.info(message);		
                        return;		
                    case msal.LogLevel.Verbose:		
                        console.debug(message);		
                        return;		
                    case msal.LogLevel.Warning:		
                        console.warn(message);		
                        return;		
                }	
            }	
        }	
    }
};

/**
 * Scopes you add here will be prompted for user consent during sign-in.
 * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
 * For more information about OIDC scopes, visit: 
 * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
 */
const loginRequest = {
    scopes: ["User.Read"]
};

/**
 * Add here the scopes to request when obtaining an access token for MS Graph API. For more information, see:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md
 */
const tokenRequest = {
    scopes: ["User.Read", "Mail.Read"],
    forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};

Skapa fortfarande en fil med namnet graphConfig.js i appmappen. Lägg till följande kod för att ge ditt program konfigurationsparametrarna för att anropa Microsoft Graph API:

// Add here the endpoints for MS Graph API services you would like to use.
const graphConfig = {
    graphMeEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me",
    graphMailEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me/messages"
};

Ändra värdena i avsnittet enligt beskrivningen graphConfig här:

  • Enter_the_Graph_Endpoint_Here är instansen av Microsoft Graph API som programmet ska kommunicera med.
    • För den globala Microsoft Graph API-slutpunkten ersätter du båda instanserna av den här strängen med https://graph.microsoft.com.
    • Slutpunkter i nationella molndistributioner finns i Nationella molndistributioner i Microsoft Graph-dokumentationen.

Värdena graphMeEndpoint och graphMailEndpoint i din graphConfig.js bör likna följande om du använder den globala slutpunkten:

graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
graphMailEndpoint: "https://graph.microsoft.com/v1.0/me/messages"

Använd Microsoft Authentication Library (MSAL) för att logga in användare

Pop-up

I appmappen skapar du en fil med namnet authPopup.js och lägger till följande autentiserings- och tokeninsamlingskod för popup-fönstret för inloggning:

// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);

let username = "";

function selectAccount() {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */

    const currentAccounts = myMSALObj.getAllAccounts();
    if (currentAccounts.length === 0) {
        return;
    } else if (currentAccounts.length > 1) {
        // Add choose account code here
        console.warn("Multiple accounts detected.");
    } else if (currentAccounts.length === 1) {
        username = currentAccounts[0].username;
        showWelcomeMessage(username);
    }
}

function handleResponse(response) {

    /**
     * To see the full list of response object properties, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#response
     */

    if (response !== null) {
        username = response.account.username;
        showWelcomeMessage(username);
    } else {
        selectAccount();
    }
}

function signIn() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    myMSALObj.loginPopup(loginRequest)
        .then(handleResponse)
        .catch(error => {
            console.error(error);
        });
}

function signOut() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    const logoutRequest = {
        account: myMSALObj.getAccountByUsername(username),
        postLogoutRedirectUri: msalConfig.auth.redirectUri,
        mainWindowRedirectUri: msalConfig.auth.redirectUri
    };

    myMSALObj.logoutPopup(logoutRequest);
}

function getTokenPopup(request) {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */
    request.account = myMSALObj.getAccountByUsername(username);
    
    return myMSALObj.acquireTokenSilent(request)
        .catch(error => {
            console.warn("silent token acquisition fails. acquiring token using popup");
            if (error instanceof msal.InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return myMSALObj.acquireTokenPopup(request)
                    .then(tokenResponse => {
                        console.log(tokenResponse);
                        return tokenResponse;
                    }).catch(error => {
                        console.error(error);
                    });
            } else {
                console.warn(error);   
            }
    });
}

function seeProfile() {
    getTokenPopup(loginRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

function readMail() {
    getTokenPopup(tokenRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMailEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

selectAccount();

Omdirigera

Skapa en fil med namnet authRedirect.js i appmappenoch lägg till följande autentiserings- och tokeninsamlingskod för inloggningsomdirigering:

// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);

let username = "";

/**
 * A promise handler needs to be registered for handling the
 * response returned from redirect flow. For more information, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/acquire-token.md
 */
myMSALObj.handleRedirectPromise()
    .then(handleResponse)
    .catch((error) => {
        console.error(error);
    });

function selectAccount () {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */

    const currentAccounts = myMSALObj.getAllAccounts();

    if (currentAccounts.length === 0) {
        return;
    } else if (currentAccounts.length > 1) {
        // Add your account choosing logic here
        console.warn("Multiple accounts detected.");
    } else if (currentAccounts.length === 1) {
        username = currentAccounts[0].username;
        showWelcomeMessage(username);
    }
}

function handleResponse(response) {
    if (response !== null) {
        username = response.account.username;
        showWelcomeMessage(username);
    } else {
        selectAccount();
    }
}

function signIn() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    myMSALObj.loginRedirect(loginRequest);
}

function signOut() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    const logoutRequest = {
        account: myMSALObj.getAccountByUsername(username),
        postLogoutRedirectUri: msalConfig.auth.redirectUri,
    };

    myMSALObj.logoutRedirect(logoutRequest);
}

function getTokenRedirect(request) {
    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */
    request.account = myMSALObj.getAccountByUsername(username);

    return myMSALObj.acquireTokenSilent(request)
        .catch(error => {
            console.warn("silent token acquisition fails. acquiring token using redirect");
            if (error instanceof msal.InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return myMSALObj.acquireTokenRedirect(request);
            } else {
                console.warn(error);   
            }
        });
}

function seeProfile() {
    getTokenRedirect(loginRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

function readMail() {
    getTokenRedirect(tokenRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMailEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

Så här fungerar koden

När en användare väljer knappen Logga in för första gången signIn anropar loginPopup metoden för att logga in användaren. Metoden loginPopup öppnar ett popup-fönster med Microsofts identitetsplattform slutpunkten för att fråga och verifiera användarens autentiseringsuppgifter. Efter en lyckad inloggning initierar msal.js auktoriseringskodflödet.

Nu skickas en PKCE-skyddad auktoriseringskod till den CORS-skyddade tokenslutpunkten och byts ut mot token. En ID-token, åtkomsttoken och uppdateringstoken tas emot av ditt program och bearbetas av msal.js, och informationen i token cachelagras.

ID-token innehåller grundläggande information om användaren, till exempel deras visningsnamn. Om du planerar att använda data som tillhandahålls av ID-token måste serverdelsservern verifiera den för att garantera att token har utfärdats till en giltig användare för ditt program.

Åtkomsttoken har en begränsad livslängd och upphör att gälla efter 24 timmar. Uppdateringstoken kan användas för att tyst hämta nya åtkomsttoken.

Det SPA som du har skapat i den här självstudien anropar acquireTokenSilent och/eller acquireTokenPopup hämtar en åtkomsttoken som används för att fråga Microsoft Graph API om användarprofilinformation. Om du behöver ett exempel som validerar ID-token kan du läsa exempelprogrammet active-directory-javascript-singlepageapp-dotnet-webapi-v2 på GitHub. Exemplet använder ett ASP.NET webb-API för tokenverifiering.

Hämta en användartoken interaktivt

Efter den första inloggningen bör din app inte be användarna att autentisera igen varje gång de behöver komma åt en skyddad resurs (d.s. för att begära en token). Om du vill förhindra sådana begäranden om autentisering anropar du acquireTokenSilent. Det finns dock vissa situationer där du kan behöva tvinga användare att interagera med Microsofts identitetsplattform. Till exempel:

  • Användarna måste ange sina autentiseringsuppgifter igen eftersom lösenordet har upphört att gälla.
  • Ditt program begär åtkomst till en resurs och du behöver användarens medgivande.
  • Tvåfaktorsautentisering krävs.

Anrop acquireTokenPopup öppnar ett popup-fönster (eller acquireTokenRedirect omdirigerar användare till Microsofts identitetsplattform). I det fönstret måste användarna interagera genom att bekräfta sina autentiseringsuppgifter, ge medgivande till den nödvändiga resursen eller slutföra tvåfaktorautentiseringen.

Hämta en token obevakat

Metoden acquireTokenSilent hanterar tokenförvärv och förnyelse utan någon användarinteraktion. När loginPopup (eller loginRedirect) körs för första gången acquireTokenSilent är den metod som ofta används för att hämta token som används för att komma åt skyddade resurser för efterföljande anrop. (Anrop för att begära eller förnya token görs tyst.) acquireTokenSilent kan misslyckas i vissa fall. Användarens lösenord kan till exempel ha upphört att gälla. Ditt program kan hantera det här undantaget på två sätt:

  1. Ring ett anrop till acquireTokenPopup omedelbart för att utlösa en uppmaning om användarinloggning. Det här mönstret används ofta i onlineprogram där det inte finns något oautentiserat innehåll i programmet som är tillgängligt för användaren. Exemplet som genereras av den här guidade installationen använder det här mönstret.
  2. Ange visuellt för användaren att en interaktiv inloggning krävs så att användaren kan välja rätt tid för att logga in, eller så kan programmet försöka acquireTokenSilent igen vid ett senare tillfälle. Den här tekniken används ofta när användaren kan använda andra funktioner i programmet utan att störas. Det kan till exempel finnas oautentiserat innehåll i programmet. I den här situationen kan användaren bestämma när de vill logga in för att komma åt den skyddade resursen eller uppdatera den inaktuella informationen.

Kommentar

I den här självstudien loginPopup används metoderna och acquireTokenPopup som standard. Om du använder Internet Explorer rekommenderar vi att du använder loginRedirect metoderna och acquireTokenRedirect på grund av ett känt problem med Internet Explorer och popup-fönster. Ett exempel på hur du uppnår samma resultat med hjälp av omdirigeringsmetoder finns i authRedirect.js på GitHub.

Anropa Microsoft Graph API

Skapa en fil med namnet graph.js i appmappen och lägg till följande kod för att göra REST-anrop till Microsoft Graph API:

/** 
 * Helper function to call MS Graph API endpoint
 * using the authorization bearer token scheme
*/
function callMSGraph(endpoint, token, callback) {
    const headers = new Headers();
    const bearer = `Bearer ${token}`;

    headers.append("Authorization", bearer);

    const options = {
        method: "GET",
        headers: headers
    };

    console.log('request made to Graph API at: ' + new Date().toString());

    fetch(endpoint, options)
        .then(response => response.json())
        .then(response => callback(response, endpoint))
        .catch(error => console.log(error));
}

I exempelprogrammet som skapades i den här självstudien callMSGraph() används metoden för att göra en HTTP-begäran GET mot en skyddad resurs som kräver en token. Begäran returnerar sedan innehållet till anroparen. Den här metoden lägger till den förvärvade token i HTTP-auktoriseringshuvudet. I exempelprogrammet som skapades i den här självstudien är den skyddade resursen Microsoft Graph API me-slutpunkten som visar den inloggade användarens profilinformation.

Testa ditt program

Du har slutfört skapandet av programmet och är nu redo att starta Node.js-webbservern och testa appens funktioner.

  1. Starta Node.js-webbservern genom att köra följande kommando från roten i projektmappen:

    npm start
    
  2. I webbläsaren navigerar du till http://localhost:3000 eller http://localhost:<port>, där <port> är porten som webbservern lyssnar på. Du bör se innehållet i din index.html-fil och knappen Logga in .

Logga in på programmet

När webbläsaren har läst in filen index.html väljer du Logga in. Du uppmanas att logga in med Microsofts identitetsplattform:

Web browser displaying sign-in dialog

Första gången du loggar in på ditt program uppmanas du att ge det åtkomst till din profil och logga in dig:

Content dialog displayed in web browser

Om du godkänner de begärda behörigheterna visar webbprogrammet ditt användarnamn, vilket betyder att inloggningen har slutförts:

Results of a successful sign-in in the web browser

Anropa Graph API

När du har loggat in väljer du Se profil för att visa användarprofilinformationen som returnerades i svaret från anropet till Microsoft Graph-API:et:

Profile information from Microsoft Graph displayed in the browser

Mer information om omfång och delegerade behörigheter

Microsoft Graph API kräver user.read-omfånget för att läsa en användares profil. Som standard läggs det här omfånget automatiskt till i varje program som är registrerat i administrationscentret för Microsoft Entra. Andra API:er för Microsoft Graph samt anpassade API:er för serverdelsservern kan kräva ytterligare omfång. Till exempel kräver Microsoft Graph API-omfånget Mail.Read för att kunna visa användarens e-post.

När du lägger till omfång kan användarna uppmanas att ge ytterligare medgivande för de tillagda omfången.

Om ett serverdels-API inte kräver något omfång, vilket inte rekommenderas, kan du använda clientId som omfång i anropen för att hämta token.

Hjälp och support

Om du behöver hjälp, vill rapportera ett problem eller vill lära dig mer om dina supportalternativ kan du läsa Hjälp och support för utvecklare.

Nästa steg

  • Läs mer genom att skapa ett React-program med en sida (SPA) som loggar in användare i följande självstudieserie i flera delar.