注销用户

在开始之前,请确保了解如何登录获取令牌和管理令牌生存期

注销

MSAL 的注销过程需要执行两个步骤。

  1. 清除 MSAL 缓存。
  2. 清除身份服务器上的会话。

PublicClientApplication 对象公开两个执行这些操作的 API。

msalInstance.logoutRedirect();
msalInstance.logoutPopup();

这些 API 将清除任何用户和会话数据的令牌缓存,然后将浏览器窗口或弹出窗口导航到服务器的注销页。 然后,服务器将提示用户选择要注销的帐户,并重定向回你的 postLogoutRedirectUri 帐户,前提是满足以下条件:

  1. 该 URI 已在应用注册中注册为回复 URL
  2. URI 作为 postLogoutRedirectUriPublicClientApplication 配置或注销请求中提供
  3. 用户与身份提供方之间存在有效会话
  4. (MSA 场景)在应用注册中配置了前端通道注销 URL

如果上述任一条件未满足,页面(或弹出窗口)将保留在标识提供者的注销页面上。

重要: 如果此注销导航以任何方式中断,可能会清除 MSAL 缓存,但会话仍可能保留在服务器上。 在返回到应用程序之前,请确保导航完全完成。

const msalConfig = {
    auth: {
        clientId: 'your_client_id',
        authority: 'https://login.microsoftonline.con/{your_tenant_id}',
        redirectUri: 'https://contoso.com',
        postLogoutRedirectUri: 'https://contoso.com/homepage'
    }
};

请求对象

可以将配置选项提供给每个注销 API,以自定义行为:

logoutRedirect

使用 logoutRedirect 将清除用户令牌的本地缓存,然后将窗口重定向到服务器注销页。 logoutRedirect 返回的 Promise 预计不会解析,但如果需要在重定向启动前阻止其他代码运行,你可以等待它。

可通过提供配置选项来自定义其行为:

const currentAccount = msalInstance.getAccount({ homeAccountId });
await msalInstance.logoutRedirect({
    account: currentAccount,
    postLogoutRedirectUri: "https://contoso.com/loggedOut"
});

跳过服务器注销

Warning

跳过服务器注销意味着用户的会话将在服务器上保持活动状态,并且可以重新登录到应用程序,而无需再次提供凭据。

如果您希望应用程序仅执行本地注销,可以为请求中的 onRedirectNavigate 参数提供一个回调函数,并使该回调返回 false。

msalInstance.logoutRedirect({
    onRedirectNavigate: (url) => {
        // Return false if you would like to stop navigation after local logout
        return false;
    }
});

logoutPopup

API logoutPopup 将在弹出窗口中打开服务器注销页,使应用程序能够保持其当前状态。 因此,在选择使用弹出窗口注销时,与 logoutRedirect 相比有一些额外的注意事项:

  • logoutPopup 返回的 Promise 预计在弹出窗口关闭后解析
  • postLogoutRedirectUri 是 MSAL 在注销完成后能够关闭弹出窗口所必需的
  • postLogoutRedirectUri 将在弹出窗口中打开,而不是主框架。 如果需要在注销后重定向顶级应用,可以在 mainWindowRedirectUri 注销请求上使用参数。

可提供配置选项以自定义其行为。

const currentAccount = msalInstance.getAccount({ homeAccountId });
await msalInstance.logoutPopup({
    account: currentAccount,
    postLogoutRedirectUri: "https://contoso.com/loggedOut",
    mainWindowRedirectUri: "https://contoso.com/homePage",
    popupWindowAttributes: {
        popupSize: {
            height: 100,
            width: 100
        },
        popupPosition: {
            top: 100,
            left: 100
        }
    }
});

无提示注销

如果客户端应用为 ID 令牌启用了 login_hint 可选声明,则可以利用 ID 令牌的 login_hint 声明,在使用 logoutRedirectlogoutPopup 时执行“静默”或无提示注销。 有两种方法可以实现无提示的注销:

选项 1:让 MSAL 自动从帐户的 ID 令牌声明中解析 login_hint

第一种也是最简单的方法,是将要结束其会话的账户对象提供给注销 API。 MSAL 将检查帐户的 ID 令牌中是否包含 login_hint 声明,并自动将其作为 logout_hint 添加到结束会话请求中,以跳过帐户选取器提示。

const currentAccount = msalInstance.getAccount({ homeAccountId });
// The account's ID Token must contain the login_hint optional claim to avoid the account picker
await msalInstance.logoutRedirect({ account: currentAccount});

选项 2:在注销请求中手动设置 logoutHint 选项

或者,如果你更愿意手动设置 logoutHint,则可以在应用中提取 login_hint 声明,并将其设置为注销请求中的 logoutHint

const currentAccount = msalInstance.getAccount({ homeAccountId });

// Extract login hint to use as logout hint
const logoutHint = currentAccount.idTokenClaims.login_hint;
await msalInstance.logoutPopup({ logoutHint: logoutHint });

注意:根据你选择的 API(重定向/弹出窗口),应用仍将重定向或打开弹出窗口以终止服务器会话。区别在于用户不会看到或必须与服务器的帐户选取器提示进行交互。

前端通道注销

Microsoft Entra ID和Azure AD B2C 支持 OAuth 前端通道注销功能,该功能可在用户启动注销时跨所有应用程序进行单一注销。 若要通过 MSAL.js利用此功能,请执行以下步骤:

  1. 在应用程序中,创建专用注销页。 此页面 不应 执行任何其他功能,例如在页面加载时获取令牌(有关详细信息,请参阅下文)。 请注意,此页面将在隐藏的 iframe 中加载,并且对于 Microsoft Entra ID 和 MSA 用户,将包含 isssid 查询参数。
  2. 在 Microsoft Entra 管理中心,导航到应用程序的“身份验证”页,并在“前端通道注销 URL”下注册步骤 1 中的页面。 请注意,此页面必须通过 https 加载。

前端通道注销页面的要求

应生成用于前端通道注销的页面,如下所示:

  1. 在页面加载时,自动调用 MSAL logoutRedirect API。
  2. PublicClientApplication 配置中,将 system.allowRedirectInIframe 设置为 true
  3. 调用 logout时,我们建议阻止 iframe 中的重定向到注销页面(请参阅 上图)。

Example:

const msal = new PublicClientApplication({
    auth: {
        clientId: "my-client-id"
    },
    system: {
        allowRedirectInIframe: true
    }
})

// Automatically on page load
msal.logoutRedirect({
    onRedirectNavigate: () => {
        // Return false to stop navigation after local logout
        return false;
    }
});

现在,当用户注销另一个应用程序时,应用程序的前端通道注销 URL 将加载到隐藏的 iframe 中,MSAL.js 将清除其缓存以完成单一注销。

注释

前通道注销并不总是受到各浏览器的支持。 Chromium 启用了 存储分区,Firefox 也支持 类似的标准,从而限制应用执行前通道注销。 有关本主题的官方 Entra 文档,请参阅 在不使用第三方 Cookie 的情况下对前端通道注销的限制

前端通道注销示例

以下示例演示如何使用 MSAL.js实现前端通道注销:

Events

如果应用的不同部分需要在无法直接访问由 logoutRedirectlogoutPopup 返回的 Promise 的情况下响应登出状态,可以使用 事件 API

当注销成功或失败时,以及使用 logoutPopup 打开弹出窗口时,都会发出事件。

重要说明

  • 如果未将帐户传递到注销 API,或者没有 EndSessionRequest 对象,它将注销所有帐户。
  • 如果将帐户传递到注销 API,MSAL 将仅清除与该帐户相关的令牌。
  • 服务器注销是一项便利功能,因此会尽力而为。 只要本地应用程序缓存已成功清除,注销 API 就会成功解析,无论服务器注销是否成功。

后续步骤

深入了解更高级的主题,例如: