ユーザーをサインインして、JavaScript シングルページ アプリケーション (SPA) から Microsoft Graph API を呼び出すSign in users and call the Microsoft Graph API from a JavaScript single-page application (SPA)

このガイドでは、JavaScript のシングルページ アプリケーション (SPA) で次のことを行う方法について説明します。This guide demonstrates how a JavaScript single-page application (SPA) can:

  • 個人用アカウントと職場または学校アカウントへのサインインSign in personal accounts, as well as work and school accounts
  • アクセス トークンの取得Acquire an access token
  • Microsoft ID プラットフォーム エンドポイントのアクセス トークンを必要とする Microsoft Graph API などの API の呼び出しCall the Microsoft Graph API or other APIs that require access tokens from the Microsoft identity platform endpoint

注意

Microsoft ID プラットフォームを初めて使用する場合は、「クイックスタート: JavaScript SPA 内でユーザーをサインインさせ、アクセス トークンを取得する」から始めることをお勧めします。If you are new to the Microsoft identity platform, we recommend you start with the Sign in users and get an access token in a JavaScript SPA quickstart.

このガイドで生成されたサンプル アプリの動作How the sample app generated by this guide works

このチュートリアルで生成されたサンプル アプリの動作の紹介

詳細情報More information

このガイドで作成したサンプル アプリケーションにより、JavaScript SPA で、Microsoft Graph API、または Microsoft ID プラットフォーム エンドポイントのトークンを受け取る Web API に対してクエリを実行できるようになります。The sample application created by this guide enables a JavaScript SPA to query the Microsoft Graph API or a web API that accepts tokens from the Microsoft identity platform endpoint. このシナリオでは、ユーザーのサインイン後に、アクセス トークンが要求され、Authorization ヘッダーを介して HTTP 要求に追加されます。In this scenario, after a user signs in, an access token is requested and added to HTTP requests through the authorization header. このトークンは、MS Graph API からユーザーのプロファイルとメールを取得する際に使用します。This token will be used to acquire the user's profile and mails via MS Graph API. トークンの取得と更新は、Microsoft Authentication Library (MSAL) for JavaScript で処理されます。Token acquisition and renewal are handled by the Microsoft Authentication Library (MSAL) for JavaScript.

ライブラリLibraries

このガイドでは、次のライブラリを使用します。This guide uses the following library:

ライブラリLibrary 説明Description
msal.jsmsal.js JavaScript 用 Microsoft Authentication LibraryMicrosoft Authentication Library for JavaScript

Web サーバーまたはプロジェクトの設定Set up your web server or project

代わりにこのサンプルのプロジェクトをダウンロードすることもできます。Prefer to download this sample's project instead? プロジェクト ファイルのダウンロードDownload the project files.

コード サンプルを実行する前に構成する場合は、構成手順に進んでください。To configure the code sample before you execute it, skip to the configuration step.

前提条件Prerequisites

  • このチュートリアルを実行するには、Node.js.NET CoreVisual Studio 2017 と統合された IIS Express などのローカル Web サーバーが必要です。To run this tutorial, you need a local web server, such as Node.js, .NET Core, or IIS Express integration with Visual Studio 2017.

  • このガイドの手順は、Node.js で構築された Web サーバーに基づいています。Instructions in this guide are based on a web server built in Node.js. 統合開発環境 (IDE) としては Visual Studio Code の使用をお勧めします。We recommend using Visual Studio Code as your integrated development environment (IDE).

プロジェクトを作成するCreate your project

Node.js がインストールされていることを確認し、アプリケーションをホストするフォルダーを作成します。Make sure you have Node.js installed, and then create a folder to host your application. そこに、index.html ファイルを提供する簡単な Express Web サーバーを実装します。There, we will implement a simple Express web server to serve your index.html file.

  1. まず、Visual Studio Code 統合ターミナルを使用して、ご使用のプロジェクト フォルダーを検索し、NPM を使用して Express をインストールします。First, using Visual Studio Code integrated terminal, locate your project folder, and then install Express using NPM.

  2. 次に、server.js という名前の .js ファイルを作成し、次のコードを追加します。Next, create a .js file named server.js, and then add the following code:

    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 morgan module to log all requests.
    app.use(morgan('dev'));
    
    // Set the front-end folder to serve public assets.
    app.use(express.static('JavaScriptSPA'))
    
    // Set up a route for index.html.
    app.get('*', function (req, res) {
        res.sendFile(path.join(__dirname + '/index.html'));
    });
    
    // Start the server.
    app.listen(port);
    console.log('Listening on port ' + port + '...');
    

これで、SPA を提供する簡単なサーバーが完成しました。You now have a simple server to serve your SPA. このチュートリアルの最後に完成する予定のフォルダー構造は次のとおりです。The intended folder structure at the end of this tutorial is as follows:

完成予定の SPA フォルダー構造を表すテキスト

SPA UI を作成するCreate the SPA UI

  1. JavaScript SPA の index.html ファイルを作成します。Create an index.html file for your JavaScript SPA. このファイルは、Bootstrap 4 Framework で作成された UI を実装し、構成、認証、API 呼び出しのためのスクリプト ファイルをインポートします。This file implements a UI built with Bootstrap 4 Framework and imports script files for configuration, authentication and API call.

    index.html ファイルに、次のコードを追加します。In the index.html file, add the following code:

    <!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 type="text/javascript" src="https://alcdn.msauth.net/lib/1.2.1/js/msal.js" integrity="sha384-9TV1245fz+BaI+VvCjMYL0YDMElLBwNS84v3mY57pXNOt6xcUYch2QLImaTahcOP" crossorigin="anonymous"></script>
        <script type="text/javascript">
          if(typeof Msal === 'undefined')document.write(unescape("%3Cscript src='https://alcdn.msftauth.net/lib/1.2.1/js/msal.js' type='text/javascript' integrity='sha384-m/3NDUcz4krpIIiHgpeO0O8uxSghb+lfBTngquAo2Zuy2fEF+YgFeP08PWFo5FiJ' crossorigin='anonymous'%3E%3C/script%3E"));
        </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">
      </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 next line with authRedirect.js if you would like 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>
    

    ヒント

    上記のスクリプトにある MSAL.js のバージョンを、MSAL.js リリースの最新のリリース バージョンに置き換えることができます。You can replace the version of MSAL.js in the preceding script with the latest released version under MSAL.js releases.

  2. 次に、DOM 要素にアクセスして更新する ui.js という名前の .js ファイルを作成し、次のコードを追加します。Now, create a .js file named ui.js, which will access and update DOM elements, and add the following code:

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

アプリケーションの登録Register your application

認証に進む前に、アプリケーションを Azure Active Directory に登録します。Before proceeding further with authentication, register your application on Azure Active Directory.

  1. Azure portal にサインインします。Sign in to the Azure portal.
  2. お使いのアカウントで複数のテナントにアクセスできる場合は、右上でそのアカウントを選択した後、使用する Azure AD テナントにポータル セッションを設定します。If your account gives you access to more than one tenant, select the account at the upper right, and then set your portal session to the Azure AD tenant that you want to use.
  3. 開発者用の Microsoft ID プラットフォームの [アプリの登録] ページに移動します。Go to the Microsoft identity platform for developers App registrations page.
  4. [アプリケーションの登録] ページが表示されたら、アプリケーションの名前を入力します。When the Register an application page appears, enter a name for your application.
  5. [サポートされているアカウントの種類] で、 [Accounts in any organizational directory and personal Microsoft accounts](任意の組織のディレクトリ内のアカウントと個人用の Microsoft アカウント) を選択します。Under Supported account types, select Accounts in any organizational directory and personal Microsoft accounts.
  6. [リダイレクト URI] セクションで、ドロップダウン リストから Web プラットフォームを選択し、お使いの Web サーバーに基づいたアプリケーション URL に値を設定します。In the Redirect URI section, select the Web platform from the drop-down list, and then set the value to the application URL that's based on your web server.
  7. [登録] を選択します。Select Register.
  8. 後で使用するために、アプリの [概要] ページで、 [アプリケーション (クライアント) ID] の値を書き留めます。On the app Overview page, note the Application (client) ID value for later use.
  9. このクイック スタートでは、暗黙的な許可フローを有効にする必要があります。This quickstart requires the Implicit grant flow to be enabled. 登録済みのアプリケーションの左側のウィンドウで、 [認証] を選択します。In the left pane of the registered application, select Authentication.
  10. [詳細設定][暗黙的な許可] で、 [ID トークン] チェック ボックスと [アクセス トークン] チェック ボックスをオンにします。In Advanced settings, under Implicit grant, select the ID tokens and Access tokens check boxes. このアプリではユーザーのサインインを実行して API を呼び出す必要があるため、ID トークンとアクセス トークンが必要です。ID tokens and access tokens are required because this app must sign in users and call an API.
  11. [保存] を選択します。Select Save.

Node.js でリダイレクト URL を設定するSet a redirect URL for Node.js

Node.js の場合は、Web サーバーのポートを server.js ファイルで設定できます。For Node.js, you can set the web server port in the server.js file. このチュートリアルでは、ポート 3000 を使用しますが、使用可能なその他の任意のポートを使用できます。This tutorial uses port 3000, but you can use any other available port.

アプリケーション登録情報の中にリダイレクト URL を設定するには、 [アプリケーションの登録] ウィンドウに切り替え、以下のいずれかを行います。To set up a redirect URL in the application registration information, switch back to the Application Registration pane, and do either of the following:

  • リダイレクト URL として http://localhost:3000/ を設定します。Set http://localhost:3000/ as the Redirect URL.
  • カスタム TCP ポートを使用している場合は、 http://localhost:<port>/ を使用します (ここで、 <port> はカスタム TCP ポート番号です)。If you're using a custom TCP port, use http://localhost:<port>/ (where <port> is the custom TCP port number).
    1. [URL] の値をコピーします。Copy the URL value.
    2. [アプリケーション登録] ウィンドウに切り替え、コピーした値を リダイレクト URL として貼り付けます。Switch back to the Application Registration pane, and paste the copied value as the Redirect URL.

JavaScript SPA の構成Configure your JavaScript SPA

authConfig.js という名前の新しい .js ファイルを作成します。このファイルには、認証用の構成パラメーターを記述することになります。次のコードを追加します。Create a new .js file named authConfig.js, which will contain your configuration parameters for authentication, and add the following code:

  const msalConfig = {
    auth: {
      clientId: "Enter_the_Application_Id_Here",
      authority: "Enter_the_Cloud_Instance_Id_HereEnter_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 are having issues on IE11 or Edge
    }
  };

  // Add here scopes for id token to be used at MS Identity Platform endpoints.
  const loginRequest = {
    scopes: ["openid", "profile", "User.Read"]
  };

  // Add here scopes for access token to be used at MS Graph API endpoints.
  const tokenRequest = {
    scopes: ["Mail.Read"]
  };

各値の説明:Where:

  • <Enter_the_Application_Id_Here> は、登録したアプリケーションのアプリケーション (クライアント) ID です。<Enter_the_Application_Id_Here> is the Application (client) ID for the application you registered.
  • <Enter_the_Cloud_Instance_Id_Here> は、Azure クラウドのインスタンスです。<Enter_the_Cloud_Instance_Id_Here> is the instance of the Azure cloud. メイン (グローバル) Azure クラウドの場合は、単に「 https://login.microsoftonline.com 」と入力します。For the main or global Azure cloud, simply enter https://login.microsoftonline.com. 各国のクラウド (中国など) の場合は、「各国のクラウド」を参照してください。For national clouds (for example, China), see National clouds.
  • <Enter_the_Tenant_info_here> は、次のオプションのいずれかに設定されます。<Enter_the_Tenant_info_here> is set to one of the following options:
    • アプリケーションで "この組織のディレクトリ内のアカウントのみ" がサポートされる場合は、この値をテナント ID またはテナント名 (例: contoso.microsoft.com) に置き換えます。If your application supports accounts in this organizational directory, replace this value with the Tenant ID or Tenant name (for example, contoso.microsoft.com).
    • アプリケーションで "任意の組織のディレクトリ内のアカウント" がサポートされる場合は、この値を organizations に置き換えます。If your application supports accounts in any organizational directory, replace this value with organizations.
    • アプリケーションで "任意の組織のディレクトリ内のアカウントと、個人用の Microsoft アカウント" がサポートされる場合は、この値を common に置き換えます。If your application supports accounts in any organizational directory and personal Microsoft accounts, replace this value with common. "個人用の Microsoft アカウントのみ" にサポートを制限するには、この値を consumers に置き換えます。To restrict support to personal Microsoft accounts only, replace this value with consumers.

ユーザーのサインインに Microsoft Authentication Library (MSAL) を使用するUse the Microsoft Authentication Library (MSAL) to sign in the user

authPopup.js という名前の新しい .js ファイルを作成します。このファイルには、認証とトークン取得のロジックを記述することになります。次のコードを追加します。Create a new .js file named authPopup.js, which will contain your authentication and token acquisition logic, and add the following code:

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

詳細情報More information

ユーザーが初めて [Sign In] ボタンを選択すると、signIn メソッドによって、ユーザーがサインインするための loginPopup が呼び出されます。After a user selects the Sign In button for the first time, the signIn method calls loginPopup to sign in the user. このメソッドによって、"Microsoft ID プラットフォーム エンドポイント" のポップアップ ウィンドウが開き、ユーザーの資格情報が要求されて検証が行われます。This method opens a pop-up window with the Microsoft identity platform endpoint to prompt and validate the user's credentials. サインインに成功すると、ユーザーは元の index.html ページにリダイレクトされます。After a successful sign-in, the user is redirected back to the original index.html page. トークンが受信されて msal.js によって処理されると、トークンに含まれる情報がキャッシュされます。A token is received, processed by msal.js, and the information contained in the token is cached. このトークンは ID トークンと呼ばれ、ユーザー表示名などのユーザーに関する基本情報が含まれます。This token is known as the ID token and contains basic information about the user, such as the user display name. 何らかの目的のためにこのトークンが提供する任意のデータを使用する予定がある場合、アプリケーションの有効なユーザーに対してトークンが発行されたことを保証するために、このトークンがバックグラウンド サーバーで確実に検証される必要があります。If you plan to use any data provided by this token for any purposes, you need to make sure this token is validated by your backend server to guarantee that the token was issued to a valid user for your application.

このガイドで生成する SPA は、ユーザー プロファイル情報のため、acquireTokenSilentacquireTokenPopup、またはその両方を呼び出して、Microsoft Graph API の照会に使用されるアクセス トークンを取得します。The SPA generated by this guide calls acquireTokenSilent and/or acquireTokenPopup to acquire an access token used to query the Microsoft Graph API for user profile info. ID トークンを検証するサンプルが必要な場合は、GitHub でこのサンプル アプリケーションを参照してください。If you need a sample that validates the ID token, take a look at this sample application in GitHub. このサンプルでは、トークンの検証に ASP.NET Web API を使用しています。The sample uses an ASP.NET web API for token validation.

ユーザー トークンを対話形式で取得するGet a user token interactively

最初のサインインの後、リソースにアクセスするためのトークンを要求するたびにユーザーに再認証を求めるのは、あまり好ましくありません。After the initial sign-in, you do not want to ask users to reauthenticate every time they need to request a token to access a resource. そこで、ほとんどの場合は、acquireTokenSilent を使用してトークンを取得することをお勧めします。So acquireTokenSilent should be used most of the time to acquire tokens. ただし、ユーザーに Microsoft ID プラットフォーム エンドポイントとのやり取りを強制しなければならない場合があります。There are situations, however, where you need to force users to interact with Microsoft identity platform endpoint. たとえば、次のようになります。Examples include:

  • パスワードの有効期限が切れているため、ユーザーは資格情報を再入力する必要がある。Users need to reenter their credentials because the password has expired.
  • アプリケーションがリソースへのアクセスを要求し、ユーザーの同意が必要である。Your application is requesting access to a resource, and you need the user's consent.
  • 2 要素認証が必須である。Two-factor authentication is required.

acquireTokenPopup を呼び出すとポップアップ ウィンドウが開きます (または acquireTokenRedirect によって Microsoft ID プラットフォーム エンドポイントにユーザーがリダイレクトされます)。Calling acquireTokenPopup opens a pop-up window (or acquireTokenRedirect redirects users to the Microsoft identity platform endpoint). ユーザーはそのウィンドウ内で、自分の資格情報の確認、必要なリソースへの同意、2 要素認証の完了のいずれかの方法で操作を行う必要があります。In that window, users need to interact by confirming their credentials, giving consent to the required resource, or completing the two-factor authentication.

ユーザー トークンを自動で取得するGet a user token silently

acquireTokenSilent メソッドは、ユーザーの操作なしでトークンの取得や更新を処理します。The acquireTokenSilent method handles token acquisition and renewal without any user interaction. 最初に loginPopup (または loginRedirect) を実行した後、後続の呼び出しでは、通常、acquireTokenSilent メソッドを使用して、保護されたリソースにアクセスするためのトークンを取得します After loginPopup (or loginRedirect) is executed for the first time, acquireTokenSilent is the method commonly used to obtain tokens used to access protected resources for subsequent calls. (トークンを要求または更新するための呼び出しは自動的に行われます)。場合によっては、acquireTokenSilent が失敗することがあります。(Calls to request or renew tokens are made silently.) acquireTokenSilent may fail in some cases. たとえば、ユーザーのパスワードの期限が切れている場合です。For example, the user's password may have expired. アプリケーションでは、この例外を 2 つの方法で処理できます。Your application can handle this exception in two ways:

  1. すぐに acquireTokenPopup を呼び出し、ユーザー サインイン プロンプトをトリガーします。Make a call to acquireTokenPopup immediately, which triggers a user sign-in prompt. オンライン アプリケーション (ユーザーが使用できる非認証コンテンツが含まれていないアプリケーション) の場合は、一般に、この方法で処理します。This pattern is commonly used in online applications where there is no unauthenticated content in the application available to the user. このガイドの設定で生成したサンプルでは、このパターンを使用しています。The sample generated by this guided setup uses this pattern.

  2. ユーザーに対してアプリケーションで視覚的に対話形式でのサインインを求めることで、ユーザーが適切なタイミングでサインインできるようにし、アプリケーションがあとで acquireTokenSilent を再試行できるようにする。Applications can also make a visual indication to the user that an interactive sign-in is required, so the user can select the right time to sign in, or the application can retry acquireTokenSilent at a later time. 他に中断なく使用できる機能がアプリケーションにある場合は、一般に、この方法が使用されます。This is commonly used when the user can use other functionality of the application without being disrupted. たとえば、使用可能な非認証コンテンツがアプリケーションに含まれている場合が考えられます。For example, there might be unauthenticated content available in the application. この場合、ユーザーは、保護されたリソースにアクセスしたり、古くなった情報を更新したりするためにサインインするタイミングを決定できます。In this situation, the user can decide when they want to sign in to access the protected resource, or to refresh the outdated information.

注意

このクイックスタートでは、既定では loginPopup メソッドと acquireTokenPopup メソッドを使用します。This quickstart uses the loginPopup and acquireTokenPopup methods by default. ブラウザーとして Internet Explorer を使用している場合は、loginRedirect メソッドと acquireTokenRedirect メソッドを使用することをお勧めします。Internet Explorer には、ポップアップ ウィンドウの処理に関して既知の問題があるためです。If you are using Internet Explorer as your browser, it is recommended to use loginRedirect and acquireTokenRedirect methods, due to a known issue related to the way Internet Explorer handles pop-up windows. Redirect methods を使用して同じ結果を実現する方法については、こちらを参照してください。If you would like to see how to achieve the same result using Redirect methods, please see.

取得したトークンを使用して Microsoft Graph API を呼び出すCall the Microsoft Graph API by using the token you just acquired

  1. まず、graphConfig.js という名前の .js ファイルを作成します。このファイルには、REST エンドポイントを記述することになります。First, create a .js file named graphConfig.js, which will store your REST endpoints. 次のコードを追加します。Add the following code:

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

    各値の説明:Where:

    • <Enter_the_Graph_Endpoint_Here> は、MS Graph API のインスタンスです。<Enter_the_Graph_Endpoint_Here> is the instance of MS Graph API. グローバル MS Graph API エンドポイントの場合は、この文字列を https://graph.microsoft.com に置き換えるだけでかまいません。For the global MS Graph API endpoint, simply replace this string with https://graph.microsoft.com. 国内クラウド デプロイの場合は、Graph API のドキュメントを参照してください。For national cloud deployments, please refer to Graph API Documentation.
  2. 次に、graph.js という名前の .js ファイルを作成します。このファイルには、Microsoft Graph API の REST 呼び出しを記述することになります。次のコードを追加します。Next, create a .js file named graph.js, which will make a REST call to Microsoft Graph API, and add the following code:

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

保護された API に対する REST 呼び出しの実行についての詳細More information about making a REST call against a protected API

このガイドで作成するサンプル アプリケーションでは、callMSGraph() メソッドを使用して、トークンが必要な保護されたリソースに対して HTTP GET 要求を実行します。In the sample application created by this guide, the callMSGraph() method is used to make an HTTP GET request against a protected resource that requires a token. その後、この要求からその内容が呼び出し元に返されます。The request then returns the content to the caller. このメソッドは、取得したトークンを HTTP Authorization ヘッダーに追加します。This method adds the acquired token in the HTTP Authorization header. このガイドで作成したサンプル アプリケーションのリソースは、ユーザーのプロファイル情報を表示する Microsoft Graph API me エンドポイントです。For the sample application created by this guide, the resource is the Microsoft Graph API me endpoint, which displays the user's profile information.

コードのテストTest your code

  1. index.html ファイルの場所に基づく TCP ポートをリッスンするように、サーバーを構成します。Configure the server to listen to a TCP port that's based on the location of your index.html file. Node.js では、アプリケーション フォルダーからコマンドライン プロンプトで次のコマンドを実行することで、Web サーバーを起動してポートをリッスンします。For Node.js, start the web server to listen to the port by running the following commands at a command-line prompt from the application folder:

    npm install
    npm start
    
  2. ブラウザーに「 http://localhost:3000 」または「 http://localhost:{port} 」と入力します。port には、実際の Web サーバーのリッスン ポートを指定してください。In your browser, enter http://localhost:3000 or http://localhost:{port}, where port is the port that your web server is listening to. index.html ファイルの内容と [サインイン] ボタンが表示されるはずです。You should see the contents of your index.html file and the Sign In button.

アプリケーションのテストTest your application

ブラウザーに index.html ファイルが読み込まれたら、 [サインイン] を選択します。After the browser loads your index.html file, select Sign In. Microsoft ID プラットフォーム エンドポイントにサインインするように求められます。You're prompted to sign in with the Microsoft identity platform endpoint:

JavaScript SPA アカウント サインイン ウィンドウ

アプリケーションへの初回サインイン時には、お使いのプロファイルへのアクセスを許可してサインインすることを求められます。The first time that you sign in to your application, you're prompted to grant it access to your profile and sign you in:

[Permissions requested](アクセス許可が要求されています) ウィンドウ

アプリケーションの結果を表示するView application results

サインインすると、自分のユーザー プロファイル情報が Microsoft Graph API の応答で返されて表示されます。After you sign in, your user profile information is returned in the Microsoft Graph API response that's displayed:

Microsoft Graph API 呼び出しの結果

スコープと委任されたアクセス許可の詳細More information about scopes and delegated permissions

Microsoft Graph API には、ユーザーのプロファイルを読み取るための user.read スコープが必要です。The Microsoft Graph API requires the user.read scope to read a user's profile. このスコープは既定で、登録ポータルに登録されているすべてのアプリケーションで自動的に追加されます。By default, this scope is automatically added in every application that's registered on the registration portal. Microsoft Graph の他の API や、バックエンド サーバーのカスタム API には、追加のスコープが必要な場合があります。Other APIs for Microsoft Graph, as well as custom APIs for your back-end server, might require additional scopes. たとえば、Microsoft Graph API には、ユーザーのメールを表示するための Mail.Read スコープが必要です。For example, the Microsoft Graph API requires the Mail.Read scope in order to list the user’s mails.

注意

スコープの数を増やすと、ユーザーは追加の同意を求められることがあります。The user might be prompted for additional consents as you increase the number of scopes.

バックエンド API でスコープを必要としない (推奨されません) 場合は、トークンを取得するための呼び出しでスコープとして clientId を使用できます。If a back-end API doesn't require a scope (not recommended), you can use clientId as the scope in the calls to acquire tokens.

ヘルプとサポートHelp and support

サポートが必要な場合、問題を報告する場合、またはサポート オプションについて知りたい場合は、開発者向けのヘルプとサポートに関するページを参照してください。If you need help, want to report an issue, or would like to learn about your support options, see Help and support for developers.