单页应用程序:获取用于调用 API 的令牌

使用 MSAL.jsacquireTokenSilent 获取 API 的令牌时,其模式是首先使用 方法来尝试无提示令牌请求。 调用此方法时,该库会首先检查浏览器存储中的缓存,看是否存在未过期的访问令牌,在有的情况下会将其返回。 如果未找到访问令牌或找到的访问令牌已过期,它将尝试使用其刷新令牌来获取新的访问令牌。 如果刷新令牌的 24 小时生存期也已过期,MSAL.js 会打开一个隐藏的 iframe,以通过适用于与 Microsoft Entra ID 的现有活动会话(如果有)按无提示方式请求新的授权代码,然后使用这些代码交换一组新令牌(访问和刷新令牌)。 有关 Microsoft Entra ID 中的单一登录 (SSO) 会话和令牌生存期值的详细信息,请参阅令牌生存期。 有关 MSAL.js 缓存查找策略的详细信息,请参阅:获取访问令牌

可能会因某些原因(例如密码更改,或者更新的条件访问策略)而导致以无提示方式向 Microsoft Entra ID 请求令牌失败。 而失败更常见的原因是刷新令牌的 24 小时生存期已过期以及浏览器阻止第三方 Cookie,这会阻止使用隐藏的 Iframe 继续对用户进行身份验证。 在这些情况下,应调用其中一个交互式方法(可能会提示用户)来获取令牌:

在弹出窗口或重定向体验之间进行选择

在弹出窗口和重定向体验之间进行的选择取决于应用程序流:

  • 如果不希望用户在身份验证期间离开主应用程序页,建议使用弹出窗口方法。 由于身份验证重定向发生在弹出窗口中,系统会保留主应用程序的状态。

  • 如果用户的浏览器约束或策略禁用了弹出窗口,则可使用重定向方法。 请对 Internet Explorer 浏览器使用重定向方法,因为 Internet Explorer 上具有弹出窗口的已知问题

可以设置 API 作用域,在生成访问令牌请求时需要访问令牌包括这些作用域。 可能不会在访问令牌中授予所有请求的范围。 具体取决于用户的许可。

通过弹出窗口获取令牌

以下代码将前面描述的模式与弹出体验的方法结合起来:

// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];

const accessTokenRequest = {
  scopes: ["user.read"],
  account: account,
};

publicClientApplication
  .acquireTokenSilent(accessTokenRequest)
  .then(function (accessTokenResponse) {
    // Acquire token silent success
    let accessToken = accessTokenResponse.accessToken;
    // Call your API with token
    callApi(accessToken);
  })
  .catch(function (error) {
    //Acquire token silent failure, and send an interactive request
    if (error instanceof InteractionRequiredAuthError) {
      publicClientApplication
        .acquireTokenPopup(accessTokenRequest)
        .then(function (accessTokenResponse) {
          // Acquire token interactive success
          let accessToken = accessTokenResponse.accessToken;
          // Call your API with token
          callApi(accessToken);
        })
        .catch(function (error) {
          // Acquire token interactive failure
          console.log(error);
        });
    }
    console.log(error);
  });

通过重定向获取令牌

以下模式如前文所述,但显示的是如何使用重定向方法以交互方式获取令牌。 需要在页面加载时调用并等待 handleRedirectPromise

const redirectResponse = await publicClientApplication.handleRedirectPromise();
if (redirectResponse !== null) {
  // Acquire token silent success
  let accessToken = redirectResponse.accessToken;
  // Call your API with token
  callApi(accessToken);
} else {
  // MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
  const account = publicClientApplication.getAllAccounts()[0];

  const accessTokenRequest = {
    scopes: ["user.read"],
    account: account,
  };

  publicClientApplication
    .acquireTokenSilent(accessTokenRequest)
    .then(function (accessTokenResponse) {
      // Acquire token silent success
      // Call API with token
      let accessToken = accessTokenResponse.accessToken;
      // Call your API with token
      callApi(accessToken);
    })
    .catch(function (error) {
      //Acquire token silent failure, and send an interactive request
      console.log(error);
      if (error instanceof InteractionRequiredAuthError) {
        publicClientApplication.acquireTokenRedirect(accessTokenRequest);
      }
    });
}

后续步骤

转到此方案中的下一篇文章:调用 Web API