单页应用程序:登录和退出登录

在应用程序中获取用于访问 API 的令牌之前,需要经身份验证的用户上下文。 若要对用户进行身份验证,可以使用弹出窗口和/或重定向登录方法。

如果应用程序可以访问经身份验证的用户上下文或 ID 令牌,则可跳过登录步骤,直接获取令牌。 有关详细信息,请参阅具有用户提示的单一登录 (SSO)

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

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

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

  • 如果用户的浏览器约束或策略禁用了弹出窗口,请使用重定向。 例如,Internet Explorer 上的弹出窗口存在已知问题

通过弹出窗口登录

const config = {
  auth: {
    clientId: "your_app_id",
    redirectUri: "your_app_redirect_uri", //defaults to application start page
    postLogoutRedirectUri: "your_app_logout_redirect_uri",
  },
};

const loginRequest = {
  scopes: ["User.ReadWrite"],
};

let accountId = "";

const myMsal = new PublicClientApplication(config);

myMsal
  .loginPopup(loginRequest)
  .then(function (loginResponse) {
    accountId = loginResponse.account.homeAccountId;
    // Display signed-in user content, call API, etc.
  })
  .catch(function (error) {
    //login failure
    console.log(error);
  });

使用重定向登录

const config = {
  auth: {
    clientId: "your_app_id",
    redirectUri: "your_app_redirect_uri", //defaults to application start page
    postLogoutRedirectUri: "your_app_logout_redirect_uri",
  },
};

const loginRequest = {
  scopes: ["User.ReadWrite"],
};

let accountId = "";

const myMsal = new PublicClientApplication(config);

function handleResponse(response) {
  if (response !== null) {
    accountId = response.account.homeAccountId;
    // Display signed-in user content, call API, etc.
  } else {
    // In case multiple accounts exist, you can select
    const currentAccounts = myMsal.getAllAccounts();

    if (currentAccounts.length === 0) {
      // no accounts signed-in, attempt to sign a user in
      myMsal.loginRedirect(loginRequest);
    } else if (currentAccounts.length > 1) {
      // Add choose account code here
    } else if (currentAccounts.length === 1) {
      accountId = currentAccounts[0].homeAccountId;
    }
  }
}

myMsal.handleRedirectPromise().then(handleResponse);

浏览器上的退出登录行为

若要确保安全退出一个或多个应用的登录,建议使用以下方法:

  • 在共享设备上,用户应使用浏览器的专用/隐身模式,并在他们离开设备之前关闭所有浏览器窗口。

  • 在未共享的设备上,用户应使用操作系统锁屏界面,以便在设备上锁定其整个操作系统会话或从中退出登录。 Microsoft 使用其退出登录页面提醒用户这些隐私和安全最佳做法。

有关详细信息,请参阅 Microsoft 的 Internet 隐私最佳做法

如果用户选择不使用这些建议退出登录,以下是启用退出登录功能的其他方法:

  • Microsoft OpenID Connect 的前通道注销,适用于联合退出登录。当应用与新应用共享登录状态但只管理自己的会话令牌/Cookie 时,可以使用此选项。 此实现存在一些限制,即内容将被阻止,例如浏览器阻止第三方 Cookie 的情况。

  • 弹出窗口和/或重定向,适用于本地应用退出登录。弹出窗口和重定向方法在终结点结束用户的会话,适用于本地应用。 但是,如果阻止了前通道通信,这些方法可能不会立即清除其他联合应用程序的会话。

使用弹出窗口退出登录

MSAL.js v2 及更高版本提供了一种 logoutPopup 方法,该方法可清除浏览器存储中的缓存,并打开一个指向 Microsoft Entra 退出登录页面的弹出窗口。 退出登录后,重定向默认为登录起始页,弹出窗口将关闭。

对于退出登录后的体验,可以设置 postLogoutRedirectUri 以将用户重定向到特定的 URI。 此 URI 应在应用程序注册中注册为重定向 URI。 还可配置 logoutPopup,将 mainWindowRedirectUri 作为请求的一部分进行传递,以将主窗口重定向到其他页面,例如主页或登录页面。

const config = {
  auth: {
    clientId: "your_app_id",
    redirectUri: "your_app_redirect_uri", // defaults to application start page
    postLogoutRedirectUri: "your_app_logout_redirect_uri",
  },
};

const myMsal = new PublicClientApplication(config);

// you can select which account application should sign out
const logoutRequest = {
  account: myMsal.getAccountByHomeId(homeAccountId),
  mainWindowRedirectUri: "your_app_main_window_redirect_uri",
};

await myMsal.logoutPopup(logoutRequest);

使用重定向退出登录

MSAL.js 在 v1 中提供了 logout 方法,在 v2 中提供了 logoutRedirect 方法,该方法可清除浏览器存储中的缓存,并重定向到 Microsoft Entra 退出登录页面。 退出登录后,重定向默认为登录起始页。

对于退出登录后的体验,可以设置 postLogoutRedirectUri 以将用户重定向到特定的 URI。 此 URI 应在应用程序注册中注册为重定向 URI。

由于此方法不显示 Microsoft 关于使用隐私浏览器和锁屏界面的 Internet 隐私最佳做法的提醒,因此你可能需要描述最佳做法并提醒用户关闭所有浏览器窗口。

const config = {
  auth: {
    clientId: "your_app_id",
    redirectUri: "your_app_redirect_uri", //defaults to application start page
    postLogoutRedirectUri: "your_app_logout_redirect_uri",
  },
};

const myMsal = new PublicClientApplication(config);

// you can select which account application should sign out
const logoutRequest = {
  account: myMsal.getAccountByHomeId(homeAccountId),
};

myMsal.logoutRedirect(logoutRequest);

后续步骤

转到此方案中的下一篇文章:获取应用的令牌