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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 13:38:03