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

iPhone设备Angular应用使用MSAL登录时出现interaction_in_progress错误

iPhone设备上@azure/msal-angular登录出现interaction_in_progress异常的解决办法

问题背景

使用@azure/msal-angular和@azure/msal-browser实现Angular应用登录功能时,仅iPhone设备触发以下控制台异常:

Uncaught (in promise) BrowserAuthError: interaction_in_progress: Interaction is currently in progress. Please ensure that this interaction has been completed before calling an interactive API.

Android及其他设备运行正常,登录数据可正常返回,但iPhone上的异常影响体验。已尝试更新MSAL版本、切换loginRedirect替代loginPopup,问题依旧,此前iPhone设备上运行正常。

登录核心代码如下:

login(userFlowRequest?: RedirectRequest | PopupRequest) {
  localStorage.clear();
  sessionStorage.clear();
  if (this.msalGuardConfig.interactionType === InteractionType.Popup) {
    if (this.msalGuardConfig.authRequest) {
      this.authService
        .loginPopup({
          ...this.msalGuardConfig.authRequest,
          ...userFlowRequest,
        } as PopupRequest)
        .subscribe((response: AuthenticationResult) => {
          this.authService.instance.setActiveAccount(response.account);
        });
    } else {
      this.authService
        .loginPopup(userFlowRequest)
        .subscribe((response: AuthenticationResult) => {
          this.authService.instance.setActiveAccount(response.account);
        });
    }
  } else {
    if (this.msalGuardConfig.authRequest) {
      this.authService.loginRedirect({
        ...this.msalGuardConfig.authRequest,
        ...userFlowRequest,
      } as RedirectRequest);
    } else {
      this.authService.loginRedirect(userFlowRequest);
    }
  }
}

解决方案

1. 阻止登录方法重复触发

iPhone Safari在快速点击、触摸/点击事件双重触发场景下,可能导致login方法被多次调用,MSAL检测到已有交互进程后报错。添加防重复点击锁:

isLoggingIn = false;

login(userFlowRequest?: RedirectRequest | PopupRequest) {
  if (this.isLoggingIn) return;
  this.isLoggingIn = true;

  // 原登录逻辑...

  // Popup模式下,在订阅的完成/错误回调重置状态
  this.authService.loginPopup(request)
    .subscribe({
      next: (res) => { this.authService.instance.setActiveAccount(res.account); },
      complete: () => { this.isLoggingIn = false; },
      error: () => { this.isLoggingIn = false; }
    });

  // Redirect模式下,页面跳转后会刷新,可在AppComponent的ngOnInit中重置isLoggingIn
}

2. 清理MSAL交互状态残留

MSAL会在sessionStorage中存储交互状态(如msal.interaction.status),若之前的交互异常终止(如页面意外刷新、弹窗被拦截),会导致状态残留引发误判。在登录前主动清理:

login(userFlowRequest?: RedirectRequest | PopupRequest) {
  // 仅清理MSAL交互相关状态,避免影响其他存储数据
  sessionStorage.removeItem('msal.interaction.status');
  sessionStorage.removeItem('msal.interaction.request');

  // 原登录逻辑...
}

3. 适配Safari隐私政策限制

近期Safari的跨站跟踪阻止、隐私模式可能导致MSAL状态存储异常,调整MSAL缓存配置:

MsalModule.forRoot(new PublicClientApplication({
  auth: {
    clientId: '你的clientId',
    authority: '你的authority'
  },
  cache: {
    location: 'LocalStorage', // 替换默认的SessionStorage,适配Safari隐私模式
    storeAuthStateInCookie: true // 开启Cookie存储作为 fallback,避免状态丢失
  }
}))

4. 优化路由守卫逻辑

若使用MsalGuard,iPhone上可能因路由跳转触发多次守卫检查,导致重复登录。在守卫中先检查活跃账户:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
  return this.authService.instance.getActiveAccount() 
    ? of(true) 
    : this.authService.loginRedirect({ redirectUri: state.url });
}

修改后的完整登录示例

isLoggingIn = false;

login(userFlowRequest?: RedirectRequest | PopupRequest) {
  if (this.isLoggingIn) return;
  this.isLoggingIn = true;

  // 清理MSAL交互状态残留
  sessionStorage.removeItem('msal.interaction.status');
  sessionStorage.removeItem('msal.interaction.request');

  if (this.msalGuardConfig.interactionType === InteractionType.Popup) {
    const request = this.msalGuardConfig.authRequest 
      ? { ...this.msalGuardConfig.authRequest, ...userFlowRequest } as PopupRequest 
      : userFlowRequest;

    this.authService.loginPopup(request)
      .subscribe({
        next: (response: AuthenticationResult) => {
          this.authService.instance.setActiveAccount(response.account);
        },
        complete: () => {
          this.isLoggingIn = false;
        },
        error: () => {
          this.isLoggingIn = false;
        }
      });
  } else {
    const request = this.msalGuardConfig.authRequest 
      ? { ...this.msalGuardConfig.authRequest, ...userFlowRequest } as RedirectRequest 
      : userFlowRequest;

    this.authService.loginRedirect(request);
  }
}

内容的提问来源于stack exchange,提问作者Engr Ejaz Ashraf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 11:45:23