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

如何使用@azure/msal-browser在accessToken过期时自动登录

解决方案:自动静默刷新令牌替代会话过期模态框

核心思路

既然用户已完成过登录,会话过期时直接触发静默令牌请求(acquireTokenSilent)获取新令牌,无需显示模态框。需要调整三个核心部分:移除模态框逻辑、自动触发静默请求、完善错误降级处理。


1. 移除会话过期模态框

直接删除原有的模态框代码,因为不再需要手动触发登录/登出操作:

// 删掉这段代码,或强制设置isOpen={false}
/*
<DialogSessionExpired
    isOpen={currentAccount?.expired}
    onLogin={signIn}
    onLogout={signOut}
/>
*/

2. 自动触发静默令牌请求

检测到账户会话过期时,自动调用你已实现的requestAccessToken,并更新应用内的令牌存储:

// 以React组件为例,在useEffect中监听账户状态变化
useEffect(() => {
  if (currentAccount?.expired) {
    requestAccessToken(currentAccount.homeAccountId)
      .then(newAccessToken => {
        // 更新应用中的令牌(比如存入state、Context或请求拦截器)
        setAccessToken(newAccessToken);
        // 同步更新API请求的Authorization头
        apiClient.defaults.headers.common['Authorization'] = `Bearer ${newAccessToken}`;
      })
      .catch(err => {
        console.error('静默刷新令牌失败:', err);
        // 静默请求失败时降级到登录流程(比如用户长时间未操作需重新验证)
        signIn();
      });
  }
}, [currentAccount]);

3. 优化requestAccessToken与错误处理

完善你的令牌请求函数,避免修改全局tokenRequest对象,并明确错误分支:

import { AuthenticationResult, SilentRequest, InteractionRequiredAuthError } from '@azure/msal-browser';

requestAccessToken = (homeAccountId?: string): Promise<string> => {
    // 复制tokenRequest避免污染全局配置
    const request: SilentRequest = { ...tokenRequest };
    const targetAccountId = homeAccountId || this.currentAccountId;
    const account = this.instance.getAccountByHomeId(targetAccountId as string);
    
    // 确保请求绑定到目标账户
    if (!account) throw new Error('未找到有效账户');
    request.account = account;
    
    return this.instance
      .acquireTokenSilent(request)
      .then((response: AuthenticationResult) => {
        if (!response.accessToken) {
          throw new InteractionRequiredAuthError();
        }
        return response.accessToken;
      })
      .catch(this.handleTokenError);
};

// 错误处理函数
handleTokenError = (error: any) => {
  if (error instanceof InteractionRequiredAuthError) {
    // 静默请求失败,必须用户交互时触发登录跳转
    return this.instance.acquireTokenRedirect(loginRequest);
    // 也可使用弹窗式登录:this.instance.acquireTokenPopup(loginRequest)
  } else {
    console.error('令牌请求异常:', error);
    // 其他错误场景直接登出
    signOut();
    throw error;
  }
};

4. 配置说明

  • tokenRequest中的forceRefresh: true:确保每次请求都向服务器获取新令牌,而非使用缓存,适合会话过期后的刷新场景。
  • loginRequest中的prompt: 'select_account':如果降级到登录,会让用户选择账户,可根据需求改为prompt: 'none'(但静默失败时可能无效)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:38:15