如何在React应用中实现Cognito集成Google登录时以新弹窗打开授权页面
如何在React应用中实现Cognito集成Google登录时以新弹窗打开授权页面
嘿,这个需求我之前做项目的时候刚好碰到过!默认调用Auth.federatedSignIn({provider: "google"})确实会在当前标签页跳转,要改成弹窗形式的话,得手动接管授权流程的几个环节,具体可以这么操作:
1. 手动构造Google授权URL
首先我们需要自己生成Cognito的Google授权链接,而不是直接用Amplify的默认跳转。可以从Amplify的配置里提取必要参数来拼接URL:
const getGoogleAuthUrl = () => { const { oauth } = Auth.configure(); const authParams = { domain: oauth.domain, clientId: oauth.clientId, redirectUri: oauth.redirectSignIn, responseType: 'code', // 采用授权码模式,更安全 scope: 'openid email profile' }; return `https://${authParams.domain}/oauth2/authorize?identity_provider=Google&response_type=${authParams.responseType}&client_id=${authParams.clientId}&redirect_uri=${authParams.redirectUri}&scope=${authParams.scope}`; };
2. 编写弹窗打开逻辑
接下来写一个处理登录点击的函数,用window.open打开授权弹窗,同时设置合适的尺寸让它居中显示:
const handleGoogleLogin = () => { const authUrl = getGoogleAuthUrl(); // 配置弹窗的尺寸和位置 const width = 650; const height = 600; const left = window.innerWidth / 2 - width / 2; const top = window.innerHeight / 2 - height / 2; // 打开授权弹窗 const authWindow = window.open( authUrl, 'GoogleAuthPopup', `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes` ); // 定时检查弹窗状态,避免内存泄漏 const checkPopupStatus = setInterval(() => { if (authWindow.closed) { clearInterval(checkPopupStatus); } }, 1000); };
3. 处理授权回调页面
你在Cognito里配置的redirectSignIn地址(比如/auth/callback)需要专门做一个页面,用来接收授权码并传递回主窗口:
// 在 /auth/callback 对应的React组件中 import { useEffect } from 'react'; const AuthCallback = () => { useEffect(() => { const urlParams = new URLSearchParams(window.location.search); const authCode = urlParams.get('code'); if (authCode) { // 把授权码发送给主窗口 window.opener.postMessage( { type: 'GOOGLE_AUTH_SUCCESS', code: authCode }, window.location.origin ); // 完成后关闭弹窗 window.close(); } }, []); return <div>授权中,请稍候...</div>; }; export default AuthCallback;
4. 主页面监听授权结果
最后在你的主应用页面(比如App.js)里添加消息监听,接收回调页面传来的授权码,再用Amplify完成登录流程:
import { useEffect } from 'react'; import { Auth } from 'aws-amplify'; function App() { useEffect(() => { const handleAuthMessage = (event) => { // 验证消息来源,防止恶意请求 if (event.origin !== window.location.origin) return; if (event.data.type === 'GOOGLE_AUTH_SUCCESS') { const { code } = event.data; const { oauth } = Auth.configure(); // 用授权码完成Cognito登录 Auth.federatedSignIn({ provider: 'Google', code, redirectUri: oauth.redirectSignIn }) .then((user) => { console.log('登录成功!', user); // 这里可以添加登录后的逻辑,比如跳转到首页 }) .catch((err) => { console.error('登录失败:', err); }); } }; window.addEventListener('message', handleAuthMessage); // 组件卸载时移除监听 return () => window.removeEventListener('message', handleAuthMessage); }, []); // 其他组件逻辑... } export default App;
注意事项
- 确保Cognito用户池的应用客户端中,已经把
redirectSignIn地址添加到允许的回调URL列表里 - 弹窗尺寸可以根据实际需求调整,保证Google授权页面能完整显示
- 消息监听里的
origin验证一定要做,这是安全层面的必要措施
备注:内容来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

