如何基于Google Cloud Identity Platform实现多React应用SSO?
问题根本原因
两个React应用分别运行在http://localhost:3000和http://localhost:3001,属于不同源站点,Firebase Auth默认将用户登录状态存储在当前站点的本地存储(LocalStorage/IndexedDB)中,跨源场景下无法读取共享,因此SSO不生效。
解决方案
1. 补全Google Cloud Identity Platform授权域名配置
登录Google Cloud控制台,进入Identity Platform的「设置」页面,在「授权的域」列表中,确认已经同时添加localhost:3000和localhost:3001两个地址,避免跨域调用Auth接口被拦截。
2. 调整Firebase Auth持久化策略
在两个React应用的Firebase初始化完成后、渲染StyledFirebaseAuth组件前,统一设置Auth的持久化类型为SESSION,让登录状态存储在Cookie中:
// 两个应用都要添加这段配置 import firebase from 'firebase/app'; import 'firebase/auth'; // firebase初始化代码后添加 firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION) .then(() => { // 持久化设置成功后再渲染登录组件/执行业务逻辑 });
本地开发场景可以额外修改hosts文件,给两个应用配置同根域名的别名,确保Cookie可以跨端口共享:
# hosts文件新增配置 127.0.0.1 app1.test.com app2.test.com
修改后两个应用分别通过http://app1.test.com:3000和http://app2.test.com:3001访问即可。
3. 优化react-firebaseui的登录逻辑
在两个应用的uiConfig中添加登录流程配置,同时增加登录状态前置判断,避免已登录时重复渲染登录表单:
const uiConfig = { signInFlow: 'popup', signInOptions: [ firebase.auth.EmailAuthProvider.PROVIDER_ID, ], callbacks: { signInSuccessWithAuthResult: () => { // 登录成功后的业务逻辑,返回false避免自动跳转 return false; }, }, }; // 组件内增加登录状态监听 const [user, setUser] = useState(null); useEffect(() => { const unregister = firebase.auth().onAuthStateChanged((user) => { setUser(user); }); return () => unregister(); }, []); // 仅未登录时渲染登录组件 return user ? <业务组件 /> : <StyledFirebaseAuth uiConfig={uiConfig} firebaseAuth={firebase.auth()} />;
生产环境部署建议
生产环境建议将两个应用部署在同一个根域名的不同子域名下(比如app1.yourdomain.com、app2.yourdomain.com),同时将Firebase的authDomain配置为统一的根域名关联的认证地址,即可实现跨子域名的SSO效果。
内容的提问来源于stack exchange,提问作者Arif Hossain
相关产品推荐
相关产品推荐

