You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何监听MSAL访问令牌过期事件?

MSAL访问令牌过期监听、过期时间设计及事件驱动刷新方案

一、监听访问令牌过期的方法

MSAL(Microsoft Authentication Library)提供了内置事件系统来捕获令牌生命周期相关事件,你可以通过注册回调监听令牌过期:

// 初始化MSAL实例
const msalConfig = {
  auth: {
    clientId: "YOUR_CLIENT_ID",
    authority: "https://login.microsoftonline.com/YOUR_TENANT_ID"
  }
};
const msalInstance = new msal.PublicClientApplication(msalConfig);

// 注册令牌过期事件回调
msalInstance.addEventCallback((event) => {
  if (event.eventType === "msal:tokenExpired") {
    // 处理令牌过期逻辑,比如触发刷新操作
    console.log("访问令牌已过期,准备刷新");
    handleTokenRefresh();
  }
});

你也可以主动解析令牌的exp(过期时间戳)字段预判过期,但使用内置事件是更贴合MSAL设计的方式。

二、60-90分钟过期时间的设计动机

微软将访问令牌有效期设为60-90分钟区间,核心是平衡安全性与用户体验:

  • 安全风险控制:短期令牌能大幅缩小令牌泄露后的攻击窗口——即使访问令牌被盗,攻击者的可用时间有限,降低未授权操作或数据泄露的风险。
  • 与刷新令牌的配合:遵循OAuth2.0体系设计,访问令牌负责短期授权,刷新令牌负责长期获取新访问令牌。这种拆分既保证了会话持续性,又避免了长期令牌泄露的高风险。
  • 动态场景适配:微软会根据应用场景、用户风险等级动态调整有效期——高风险场景(如敏感数据访问)用60分钟,普通场景用90分钟,在安全和操作中断频率间取最优解。
  • 行业最佳实践:短期访问令牌是OAuth2.0生态的通用设计,符合国际安全标准和身份管理领域的最佳实践。

三、事件驱动的令牌刷新方案(替代定时任务)

无需设置固定定时任务,MSAL支持基于事件和API调用结果的触发式刷新,推荐两种方式:

1. 利用MSAL内置事件触发刷新

结合msal:tokenExpired事件,在令牌过期时调用静默刷新接口:

async function handleTokenRefresh() {
  const request = {
    scopes: ["YOUR_API_SCOPES"]
  };
  try {
    const response = await msalInstance.acquireTokenSilent(request);
    // 刷新成功,更新本地令牌存储或用于后续API调用
    console.log("令牌刷新成功", response.accessToken);
  } catch (error) {
    // 静默刷新失败(如用户会话过期),触发交互式登录
    if (error instanceof msal.InteractionRequiredAuthError) {
      await msalInstance.acquireTokenPopup(request);
    }
  }
}

2. 基于API调用失败的被动刷新

在调用受保护API返回401 Unauthorized时,触发令牌刷新并重试请求,更贴合实际业务流程:

async function callProtectedApi(apiUrl) {
  const request = { scopes: ["YOUR_API_SCOPES"] };
  
  try {
    // MSAL会自动判断令牌是否需刷新,先尝试获取有效令牌
    const tokenResponse = await msalInstance.acquireTokenSilent(request);
    const response = await fetch(apiUrl, {
      headers: { Authorization: `Bearer ${tokenResponse.accessToken}` }
    });

    if (response.status === 401) {
      // 令牌已过期,刷新后重试请求
      const newTokenResponse = await msalInstance.acquireTokenSilent(request);
      return fetch(apiUrl, {
        headers: { Authorization: `Bearer ${newTokenResponse.accessToken}` }
      });
    }

    return response.json();
  } catch (error) {
    // 静默刷新失败,引导用户重新交互登录
    if (error instanceof msal.InteractionRequiredAuthError) {
      await msalInstance.acquireTokenPopup(request);
      return callProtectedApi(apiUrl);
    }
    throw error;
  }
}

注意:MSAL默认会在令牌即将过期前(通常提前5分钟)自动尝试静默刷新,大部分场景下无需手动监听,仅在特殊业务逻辑需要感知过期事件时,才需注册事件回调。

内容的提问来源于stack exchange,提问作者BobDidley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:05:17