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

React-Admin v5中React严格模式下OIDC登录流程失效求助

解决方案:通过代码修改避免StrictMode下的重复回调执行

这个问题不需要等待react-admin官方修复,你可以通过修改自身代码解决,核心是防止handleCallback方法被重复执行。

问题原因

React StrictMode在开发环境会重复调用某些函数和生命周期方法(比如组件挂载、useEffect回调等),react-admin v5对AuthProvider的回调触发逻辑和v4存在差异,导致handleCallback被执行两次。第一次调用时signinRedirectCallback已经消耗了URL中的state参数,第二次调用自然会抛出"No matching state found in storage"错误。

修复代码

你可以通过添加执行锁,确保handleCallback只处理一次回调请求:

方案1:使用全局变量(适合AuthProvider类或独立函数)

// 全局标记,确保回调只被处理一次
let isCallbackHandled = false;

async handleCallback() {
  const query = window.location.search;
  if (!query.includes("code=") && !query.includes("state=")) {
    throw new Error("Failed to handle login callback.");
  }

  // 如果已经处理过当前回调,直接返回
  if (isCallbackHandled) return;
  isCallbackHandled = true;

  try {
    await OIDCUserManager.signinRedirectCallback();
  } catch (error) {
    // 忽略因重复调用导致的state不存在错误
    if (error.message.includes("No matching state found")) {
      return;
    }
    // 抛出其他类型的错误
    throw error;
  }
}

方案2:使用useRef(适合组件内的回调逻辑)

如果你的AuthProvider是基于组件实现的,可以用React的useRef存储状态:

import { useRef } from 'react';

// 在组件内部初始化ref
const isCallbackHandled = useRef(false);

async handleCallback() {
  const query = window.location.search;
  if (!query.includes("code=") && !query.includes("state=")) {
    throw new Error("Failed to handle login callback.");
  }

  if (isCallbackHandled.current) return;
  isCallbackHandled.current = true;

  try {
    await OIDCUserManager.signinRedirectCallback();
  } catch (error) {
    if (error.message.includes("No matching state found")) {
      return;
    }
    throw error;
  }
}

额外说明

生产环境下StrictMode不会触发重复调用,所以这个修复不会影响生产环境的正常运行。如果后续react-admin官方优化了AuthProvider的回调触发逻辑,你可以再移除这个锁逻辑,但目前这个方案是最直接有效的解决办法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 02:30:00