Tutorial: Inicio de sesión de usuarios y llamada a Microsoft Graph API desde una aplicación de página única de JavaScript

En este tutorial, crea una aplicación de página única (SPA) de JavaScript que inicia la sesión de los usuarios y llama a Microsoft Graph mediante el flujo implícito de OAuth 2.0. Esta SPA usa MSAL.js v1.x, que usa el flujo de concesión implícita para las SPA. Se recomienda que todas las aplicaciones nuevas usen MSAL.js 2.x y el flujo de código de autorización con compatibilidad con PKCE y CORS. El flujo de código de autorización proporciona más seguridad que el flujo implícito.

En este tutorial, aprenderá a:

  • Crear un proyecto de JavaScript con npm
  • Registrar la aplicación en Azure Portal
  • Agregar código para admitir el inicio y el cierre de sesión de usuario
  • Agregar código para llamar a Microsoft Graph API
  • Prueba de la aplicación
  • Comprenda cómo funciona el proceso en segundo plano

Al final de este tutorial, tendrá la siguiente estructura de carpetas y archivos (por orden de creación):

sampleApp/
├── JavaScriptSPA/
│   ├── authConfig.js
│   ├── authPopup.js
│   ├── graph.js
│   ├── graphConfig.js
│   ├── index.html
│   └── ui.js
├── package.json
├── package-lock.json
├── node_modules/
│   └── ...    
└── server.js
 

Prerrequisitos

  • Node.js para ejecutar un servidor web local.
  • Visual Studio Code u otro editor para modificar archivos de proyecto.
  • Un explorador web moderno. La aplicación que se compila en este tutorial usa convenciones ES6 y no admite Internet Explorer.

Funcionamiento de la aplicación de ejemplo

Diagrama que muestra cómo funciona la aplicación de ejemplo generada en este tutorial.

La aplicación que crea en este tutorial permite que una aplicación de página única de JavaScript haga consultas a Microsoft Graph API. Esta consulta también puede funcionar para una API web configurada para aceptar tokens de la Plataforma de identidad de Microsoft. Una vez que el usuario inicia sesión, la SPA solicita un token de acceso y lo agrega a las solicitudes HTTP a través del encabezado de autorización. La SPA usará este token para adquirir el perfil y los correos electrónicos del usuario a través de Microsoft Graph API.

La biblioteca de autenticación de Microsoft (MSAL) para JavaScript administra la adquisición y renovación de los tokens.

Configuración de un proyecto o servidor web

Si lo prefiere, puede descargar los archivos del proyecto.

Para configurar el ejemplo de código antes de ejecutarlo, vaya al paso de registro.

Creación del proyecto

  1. Asegúrese de que tiene instalado Node.js y cree una carpeta para hospedar la aplicación. Asigne a la carpeta el nombre sampleApp. En esta carpeta, se crea un servidor web Express para servir el archivo index.html.

  2. Mediante un terminal (como el terminal integrado de Visual Studio Code), busque la carpeta del proyecto y entre en ella. A continuación, escriba:

    npm init
    
  3. Aparece una serie de mensajes para la creación de la aplicación. Observe que la carpeta sampleApp ahora está en minúsculas. Los elementos entre paréntesis () se generan de forma predeterminada.

    package name: (sampleapp)
    version: (1.0.0)
    description:
    entry point: (index.js)
    test command:
    git repository:
    keywords:
    author:
    license: (ISC)
    

    No dude en experimentar. Sin embargo, para los fines de este tutorial, no es necesario escribir nada. Seleccione la tecla Entrar para continuar con el siguiente símbolo del sistema.

  4. La solicitud de consentimiento final contiene la siguiente salida si no ha especificado ningún valor en el paso anterior.

    {
      "name": "sampleapp",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC"
    }
    
    
    Is this OK? (yes)
    

    Seleccione la tecla Entrar y el JSON se escribe en un archivo denominado package.json.

  5. Instale todas las dependencias necesarias escribiendo los siguientes comandos:

    npm install express --save
    npm install morgan --save
    

    Express.js es un módulo Node.js que simplifica la creación de servidores web y API. Morgan.js se usa para registrar solicitudes HTTP y errores. Al instalarlos, se crea el archivo package-lock.json y la carpeta node_modules.

  6. Cree un archivo .js denominado server.js en la carpeta actual y agregue el código siguiente:

    const express = require('express');
    const morgan = require('morgan');
    const path = require('path');
    
    //Initialize Express.
    const app = express();
    
    // Initialize variables.
    const port = 3000; // process.env.PORT || 3000;
    
    // Configure the morgan module to log all requests.
    app.use(morgan('dev'));
    
    // Set the front-end folder to serve public assets.
    app.use(express.static('JavaScriptSPA'))
    
    app.get('*', function (req, res) {
        res.sendFile(path.join(__dirname + '/JavaScriptSPA/index.html'));
    });
    
    // Start the server.
    app.listen(port);
    console.log('Listening on port ' + port + '...');
    

Ahora tiene un servidor para dar servicio a la SPA. En este momento, la estructura de carpetas debe tener este aspecto:

sampleApp/
├── package.json
├── package-lock.json
├── node_modules/
│   └── ...    
└── server.js

En los pasos siguientes, creará una carpeta para la SPA de JavaScript y configurará la interfaz de usuario (UI).

Sugerencia

Al configurar una cuenta de Azure Active Directory (Azure AD), se crea un inquilino. Se trata de una representación digital de su organización. Se asocia principalmente a un dominio, como Microsoft.com. Si quiere obtener información sobre cómo funcionan las aplicaciones con varios inquilinos, consulte el modelo de aplicación.

Creación de la interfaz de usuario de SPA

  1. Cree una nueva carpeta, JavaScriptSPA y vaya a esa carpeta.

  2. Cree un archivo index.html para la SPA. Este archivo implementa una interfaz de usuario compilada con el marco Bootstrap 4. El archivo también importa archivos de script para las llamadas de API, autenticación y configuración.

    En el archivo index.html, agregue el código siguiente:

    <!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>Quickstart | MSAL.JS Vanilla JavaScript SPA</title>
    
        <!-- msal.js with a fallback to backup CDN -->
          <script src="https://alcdn.msauth.net/browser/2.30.0/js/msal-browser.js"
     integrity="sha384-L8LyrNcolaRZ4U+N06atid1fo+kBo8hdlduw0yx+gXuACcdZjjquuGZTA5uMmUdS"
     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-o4ufwq3oKqc7IoCcR08YtZXmgOljhTggRwxP2CLbSqeXGtitAxwYaUln/05nJjit" crossorigin="anonymous">
      </head>
      <body>
        <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
          <a class="navbar-brand" href="/">MS Identity Platform</a>
          <div class="btn-group ml-auto dropleft">
            <button type="button" id="signIn" class="btn btn-secondary" onclick="signIn()">Sign In</button>
            <button type="button" id="signOut" class="btn btn-success d-none" onclick="signOut()">Sign Out</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 d-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 d-none" 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>
    
        <!-- replace the next line with authRedirect.js if you want to use the redirect flow -->
        <!-- <script type="text/javascript" src="./authRedirect.js"></script>   -->
        <script type="text/javascript" src="./authPopup.js"></script>
        <script type="text/javascript" src="./graph.js"></script>
      </body>
    </html>
    
  3. Cree un archivo denominado ui.js y agregue este código para acceder a los elementos del Document Object Model (DOM) y actualizarlos:

    // Select DOM elements to work with
    const welcomeDiv = document.getElementById("welcomeMessage");
    const signInButton = document.getElementById("signIn");
    const signOutButton = document.getElementById('signOut');
    const cardDiv = document.getElementById("card-div");
    const mailButton = document.getElementById("readMail");
    const profileButton = document.getElementById("seeProfile");
    const profileDiv = document.getElementById("profile-div");
    
    function showWelcomeMessage(account) {
      // Reconfiguring DOM elements
      cardDiv.classList.remove('d-none');
      welcomeDiv.innerHTML = `Welcome ${account.name}`;
      signInButton.classList.add('d-none');
      signOutButton.classList.remove('d-none');
    }
    
    function updateUI(data, endpoint) {
      console.log('Graph API responded at: ' + new Date().toString());
    
      if (endpoint === graphConfig.graphMeEndpoint) {
        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.length < 1) {
            alert("Your mailbox is empty!")
          } else {
            const tabList = document.getElementById("list-tab");
            tabList.innerHTML = ''; // clear tabList at each readMail call
            const tabContent = document.getElementById("nav-tabContent");
    
            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);
              }
            });
          }
      }
    }
    

Registro de la aplicación

Antes de continuar con la autenticación, registre la aplicación en Azure AD:

  1. Inicie sesión en Azure Portal.

  2. Vaya a Azure Active Directory.

  3. En el panel de la izquierda, en Administrar, seleccione Registros de aplicaciones. Después, en la barra de menús superior, seleccione Nuevo registro.

  4. Escriba un nombre para la aplicación, por ejemplo, sampleApp. Puede cambiar el nombre posteriormente, si es necesario.

  5. En Tipos de cuenta admitidos, seleccione Solo las cuentas de este directorio organizativo.

  6. En la sección URI de redirección, seleccione la plataforma Web en la lista desplegable.

    A la derecha, escriba http://localhost:3000/.

  7. Seleccione Registrar.

    Se abre la página Información general de la aplicación. Anote los valores de Id. de aplicación (cliente) y el de Id. de directorio (inquilino). Los necesitará al crear el archivo authConfig.js en pasos posteriores.

  8. En Administrar, seleccione Autenticación.

  9. En la sección Implicit grant and hybrid flows (Flujos de concesión implícita e híbridos), seleccione Tokens de id. y Tokens de acceso. Los tokens de identificador y los tokens de acceso son obligatorios, ya que esta aplicación tiene que iniciar la sesión de los usuarios y llamar a una API.

  10. Seleccione Guardar. Para volver a la página Información general, selecciónela en el panel izquierdo.

El URI de redireccionamiento se puede cambiar en cualquier momento; para ello, vaya a la página Información general y seleccione Agregar URI de redirección.

Configurar SPA de JavaScript

  1. En la carpeta JavaScriptSPA, cree un nuevo archivo, authConfig.js. A continuación, copie el código siguiente. Este código contiene los parámetros de configuración para la autenticación (id. de cliente, id. de inquilino, URI de redirección).

      const msalConfig = {
        auth: {
          clientId: "Enter_the_Application_Id_Here",
          authority: "Enter_the_Cloud_Instance_Id_Here/Enter_the_Tenant_Info_Here",
          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're having issues on Internet Explorer 11 or Edge
        }
      };
    
      // Add scopes for the ID token to be used at Microsoft identity platform endpoints.
      const loginRequest = {
        scopes: ["openid", "profile", "User.Read"]
      };
    
      // Add scopes for the access token to be used at Microsoft Graph API endpoints.
      const tokenRequest = {
        scopes: ["Mail.Read"]
      };
    
  2. Modifique los valores en la sección msalConfig. Consulte la página Información general de la aplicación para obtener estos valores:

    • Enter_the_Application_Id_Here es el valor del id. de aplicación (cliente) para la aplicación que se registró.

    • Enter_the_Cloud_Instance_Id_Here es la instancia de la nube de Azure. En el caso de la nube principal o global de Azure, escriba https://login.microsoftonline.com. Para las nubes nacionales (por ejemplo, China) consulte Nubes nacionales.

    • Reemplace Enter_the_Tenant_info_here por el identificador de directorio (inquilino) (un GUID) o el valor de nombre de inquilino (por ejemplo, contoso.onmicrosoft.com).

    • Enter_the_Redirect_URI_Here es la dirección URL predeterminada que estableció en la sección anterior: http://localhost:3000/.

Sugerencia

Hay otras opciones para Enter_the_Tenant_info_here dependiendo de lo que quiera que admita la aplicación:

  • Si la aplicación admite cuentas en cualquier directorio organizativo, reemplace este valor por organizaciones.
  • Si la aplicación admite cuentas en cualquier directorio organizativo y cuentas Microsoft personales, reemplace este valor por común. Para restringir la compatibilidad a Personal Microsoft accounts only (Solo cuentas Microsoft personales), reemplace este valor por consumidores.

Uso de MSAL para iniciar la sesión del usuario

En la carpeta JavaScriptSPA, cree un nuevo archivo .js denominado authPopup.js, que contiene la lógica de adquisición de tokens y autenticación. Agregue el código siguiente:

const myMSALObj = new Msal.UserAgentApplication(msalConfig);

function signIn() {
  myMSALObj.loginPopup(loginRequest)
    .then(loginResponse => {
      console.log('id_token acquired at: ' + new Date().toString());
      console.log(loginResponse);

      if (myMSALObj.getAccount()) {
        showWelcomeMessage(myMSALObj.getAccount());
      }
    }).catch(error => {
      console.log(error);
    });
}

function signOut() {
  myMSALObj.logout();
}

function callMSGraph(theUrl, accessToken, callback) {
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
           callback(JSON.parse(this.responseText));
        }
    }
    xmlHttp.open("GET", theUrl, true); // true for asynchronous
    xmlHttp.setRequestHeader('Authorization', 'Bearer ' + accessToken);
    xmlHttp.send();
}

function getTokenPopup(request) {
  return myMSALObj.acquireTokenSilent(request)
    .catch(error => {
      console.log(error);
      console.log("silent token acquisition fails. acquiring token using popup");

      // fallback to interaction when the silent call fails
        return myMSALObj.acquireTokenPopup(request)
          .then(tokenResponse => {
            return tokenResponse;
          }).catch(error => {
            console.log(error);
          });
    });
}

function seeProfile() {
  if (myMSALObj.getAccount()) {
    getTokenPopup(loginRequest)
      .then(response => {
        callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
        profileButton.classList.add('d-none');
        mailButton.classList.remove('d-none');
      }).catch(error => {
        console.log(error);
      });
  }
}

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

Uso de tokens para la validación

La primera vez que un usuario selecciona el botón Iniciar sesión, la función signIn que agregó al archivo authPopup.js llama a la función loginPopup de MSAL para iniciar el proceso de inicio de sesión. Esta función abre una ventana emergente que solicita al usuario que escriba sus credenciales.

Después de iniciar sesión correctamente, el usuario se redirige de nuevo a la página index.html original. El archivo msal.js recibe y procesa un token de identificador y la información del token se almacena en caché. El token de identificador contiene información básica sobre el usuario, como su nombre para mostrar. Si piensa utilizar los datos proporcionados por este token para algún propósito, asegúrese de que el servidor de back-end lo valide para garantizar que el token se emitió a un usuario válido para la aplicación.

La aplicación que cree en este tutorial llama acquireTokenSilent y/o acquireTokenPopup para adquirir un token de acceso. La aplicación usa este token para consultar Microsoft Graph API para obtener la información del perfil del usuario. Si necesita un ejemplo que valide el token de identificador, consulte la aplicación de ejemplo en GitHub, que usa una API web de ASP.NET para la validación de tokens.

Obtención de un token de usuario interactivamente

Después del inicio de sesión inicial, los usuarios no deberían necesitar volver a autenticarse cada vez que tengan que solicitar un token para acceder a un recurso. La mayoría de las veces, la aplicación usará acquireTokenSilent para adquirir tokens. Pero es posible que obligue a los usuarios a interactuar con la Plataforma de identidad de Microsoft en situaciones como estas:

  • Los usuarios deben volver a escribir las credenciales porque la contraseña expiró.
  • Una aplicación solicita acceso a un recurso y necesita el consentimiento del usuario.
  • Se requiere la autenticación en dos fases.

La llamada a acquireTokenPopup abre una ventana emergente (o acquireTokenRedirect redirige a los usuarios a la Plataforma de identidad de Microsoft). En esa ventana, los usuarios tienen que interactuar confirmando sus credenciales, dándole el consentimiento al recurso requerido o completando la autenticación en dos fases.

Obtención de un token de usuario en silencio

El método acquireTokenSilent controla la renovación y las adquisiciones de tokens sin la interacción del usuario. Después de ejecutar loginPopup (o loginRedirect) por primera vez, las llamadas posteriores usan acquireTokenSilent para obtener tokens para acceder a los recursos protegidos. (Las llamadas para solicitar o renovar tokens se realizan en modo silencioso).

El método acquireTokenSilent puede producir un error en algunos casos, como cuando expira la contraseña de un usuario. La aplicación puede abordar esta excepción de dos maneras:

  • Realizando una llamada a acquireTokenPopup inmediatamente, lo que desencadena un mensaje de inicio de sesión de usuario. Este patrón se da comúnmente en aplicaciones en línea en las que no hay ningún contenido no autenticado disponible para el usuario. En el ejemplo que se crea en este tutorial se usa este patrón.

  • Haciendo una indicación visual al usuario de que se requiere un inicio de sesión interactivo. El usuario puede seleccionar el momento adecuado para iniciar sesión, o bien, la aplicación puede reintentar ejecutar el método acquireTokenSilent en un momento posterior.

    Este patrón se suele usar cuando el usuario puede utilizar otra funcionalidad de la aplicación sin ser interrumpido. Por ejemplo, podría haber contenido no autenticado disponible en la aplicación. En esta situación, el usuario puede decidir cuándo quiere iniciar sesión para acceder al recurso protegido o para actualizar la información obsoleta.

Nota:

En este tutorial se usan los métodos loginPopup y acquireTokenPopup de forma predeterminada. Si usa Internet Explorer como explorador, se recomienda usar los métodos loginRedirect y acquireTokenRedirect debido a un problema conocido con la forma en que Internet Explorer controla las ventanas emergentes.

Si quiere ver cómo lograr el mismo resultado mediante métodos de redireccionamiento, consulte el código de ejemplo.

Llamada a Microsoft Graph API con el token adquirido

  1. En la carpeta JavaScriptSPA, cree un archivo .js denominado graphConfig.js, que almacena los puntos de conexión de Transferencia de estado representacional (REST). Agregue el código siguiente:

       const graphConfig = {
         graphMeEndpoint: "Enter_the_Graph_Endpoint_Here/v1.0/me",
         graphMailEndpoint: "Enter_the_Graph_Endpoint_Here/v1.0/me/messages"
       };
    

    Enter_the_Graph_Endpoint_Here es la instancia de Microsoft Graph API. En el caso del punto de conexión de Microsoft Graph API global, puede reemplazarlo por https://graph.microsoft.com. En el caso de las implementaciones de nube nacional, consulte la Documentación de Microsoft Graph API.

  2. Cree un archivo llamado graph.js, que realizará una llamada REST a Microsoft Graph API. Después, la SPA puede acceder a los servicios web de una manera sencilla y flexible sin ningún procesamiento. Agregue el código siguiente:

    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))
    }
    

Más información acerca de llamadas de REST a una API protegida

La aplicación de muestra que crea en este tutorial usa el método callMSGraph() para realizar una solicitud HTTP GET a un recurso protegido que requiere un token. A continuación, el método devuelve el contenido al autor de la llamada.

Este método agrega el token adquirido al encabezado de autorización HTTP. En esta aplicación de ejemplo, el recurso es el punto de conexión me de Microsoft Graph API, que muestra información del perfil del usuario.

Prueba del código

Ahora que ha configurado el código, debe probarlo:

  1. Configure el servidor para que escuche un puerto TCP que esté basado en la ubicación del archivo index.html. Para Node.js, puede iniciar el servidor web para escuchar el puerto que especificó anteriormente. Ejecute los comandos siguientes en un símbolo de la línea de comandos desde la carpeta JavaScriptSPA :

    npm install
    npm start
    
  2. En el explorador, escriba http://localhost:3000. Debería ver el contenido del archivo index.html y el botón de Iniciar sesión en la parte superior derecha de la pantalla.

Importante

Asegúrese de habilitar los elementos emergentes y los redireccionamientos para el sitio en la configuración del explorador.

Cuando el explorador haya cargado el archivo index.html, seleccione Iniciar sesión. Se le pedirá que inicie sesión con la Plataforma de identidad de Microsoft.

Captura de pantalla que muestra la ventana de inicio de sesión en la cuenta de SPA de JavaScript.

La primera vez que inicie sesión en la aplicación, se le pedirá que le conceda acceso a su perfil e inicie su sesión. Seleccione Aceptar para continuar.

Captura de pantalla que muestra la ventana en la que la aplicación solicita permisos.

Visualización de los resultados de la aplicación

Después de iniciar sesión, puede seleccionar Leer más en el nombre que se muestra. La información del perfil de usuario se devuelve en la respuesta de Microsoft Graph API mostrada.

Captura de pantalla que muestra los resultados esperados de la llamada a Microsoft Graph API.

Más información sobre los ámbitos y permisos delegados

Microsoft Graph API requiere el ámbito User.Read para leer un perfil de usuario. De forma predeterminada, este ámbito se agrega automáticamente en todas las aplicaciones que se registran en el portal de registro. Otras API de Microsoft Graph, así como las API personalizadas para el servidor back-end, pueden requerir ámbitos adicionales. Por ejemplo, Microsoft Graph API requiere el ámbito Mail.Read para mostrar los correos del usuario.

Nota:

Es posible que se pida al usuario algún consentimiento adicional a medida que aumente el número de ámbitos.

Ayuda y soporte técnico

Si necesita ayuda, desea informar de un problema o desea obtener información sobre las opciones de soporte técnico, consulte Opciones de ayuda y soporte técnico para desarrolladores.

Pasos siguientes

Profundice en el desarrollo de SPA en la Plataforma de identidad de Microsoft en la primera parte de una serie de escenarios: