You need to enable JavaScript to run this app. React微前端开发:如何向子应用传递JWT令牌与用户ID?
优惠活动
大模型
产品
解决方案
定价
更多

React微前端开发:如何向子应用传递JWT令牌与用户ID?

微前端场景下AppA与AppB的认证数据共享落地方案

结合你当前使用React + Module Federation远程加载组件的技术栈,有三个可直接落地的实现方式,完全适配你现有的代码结构:

方案1:组件Props直传(最适配当前代码的零成本方案)

你现在的代码已经是在AppA中通过React.lazy远程加载AppB导出的AuthForms组件,完全可以直接把需要共享的JWT、用户ID这类认证数据当普通React props传给子应用组件,不需要额外搭建跨应用通信机制。
改造AppA代码:

// AppA 代码调整
import React from 'react';
import { useAuthStore } from './store/authStore'; // 项目中维护认证状态的Hook/Zustand/Redux均可

const AuthForms = React.lazy(() => import('login/AuthForm'));

const App = () => {
  // 从本地认证状态中读取实时的JWT、用户ID
  const { jwt, userId } = useAuthStore(state => state);

  return (
    <div className={classes.root}>
      <div className={classes.contentWrapper}>
        <React.Suspense fallback={<p>Loading content from app 2...</p>} >
          {/* 把认证数据作为props传给远程加载的子应用组件 */}
          <AuthForms authPayload={{ jwt, userId }} />
        </React.Suspense>
      </div>
    </div>
  );
}
export default App;

改造AppB代码:

// AppB 代码调整
import React, { useEffect } from 'react';
import axios from 'axios';

const AuthForms = (props) => {
  // 直接从props中获取AppA传递的认证数据
  const { jwt, userId } = props.authPayload;

  // 初始化请求拦截器,统一给所有后端请求添加JWT鉴权头
  useEffect(() => {
    const requestInterceptor = axios.interceptors.request.use((config) => {
      config.headers.Authorization = `Bearer ${jwt}`;
      return config;
    });
    // 组件卸载时清理拦截器,避免内存泄漏
    return () => axios.interceptors.request.eject(requestInterceptor);
  }, [jwt]);

  return (
    <div className={classes.formWrapper}>
      AppB已获取JWT令牌,可正常发起带鉴权的后端请求
    </div>
  );
};
export default AuthForms;

该方案没有全局状态污染的问题,JWT更新时props会自动同步给AppB,完全遵循React组件的开发习惯,不存在跨应用数据不一致的风险。

方案2:同域共享存储读取(最省事的通用方案)

你目前已经将JWT存储在localStorage中,只要调整存储的作用域,AppB就可以直接读取令牌:

  • AppA存储JWT时,不要默认存在当前子应用的域下,要将作用域设置为顶级域名。比如AppA部署在a.example.com,存储时指定域为.example.com,同属example.com下的AppB部署在b.example.com时,就可以直接通过localStorage.getItem('jwt')读取到令牌
  • 该方案仅适用于同主域部署的场景,如果两个应用跨顶级域部署(如AppA在a.com、AppB在b.com),浏览器的存储隔离机制会导致localStorage数据无法共享
  • 为了避免读取滞后,可以搭配自定义事件做状态同步:AppA在JWT更新时,向window派发自定义事件,AppB监听事件即可拿到最新的令牌值。

方案3:全局通信通道传值(适合跨框架、独立部署的微前端场景)

如果AppB不是以远程组件的形式被AppA加载,而是独立运行、通过路由跳转嵌入到AppA容器中,可以通过全局事件通道完成数据共享:

  • AppA在认证完成、JWT更新时,把需要共享的数据挂到全局window对象上,同时派发状态更新事件:
    // AppA 认证成功后执行
    const sharedAuthData = { jwt: "xxx", userId: "123" };
    window.__MICRO_APP_SHARED_DATA__ = sharedAuthData;
    // 派发更新事件
    window.dispatchEvent(new CustomEvent("auth-update", { detail: sharedAuthData }))
    
  • AppB在初始化时,先从全局对象读取初始的认证数据,同时监听auth-update事件拿到后续的令牌更新值,写入自身的请求拦截器即可。
    如果使用qiankun、Single-SPA这类专门的微前端框架,不需要手动编写事件监听逻辑,框架本身内置了全局状态API,主应用注册状态后子应用直接订阅即可,实现逻辑完全一致。

落地注意事项

  • 认证逻辑统一收口在AppA中,不要让AppB自行存储、刷新JWT,避免出现多入口存储令牌不一致的问题
  • 仅将请求需要的访问令牌共享给子应用,刷新令牌这类高敏感信息不要暴露到可全局读取的位置
  • 如果AppB支持独立访问(不依赖AppA单独打开),可以做兜底逻辑:优先从props/全局通道读取AppA传递的认证数据,读取失败时再从localStorage取本地存储的令牌,保证独立运行时也能正常鉴权。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 15:15:04