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

SolidJS SPA中调用Auth.federatedSignIn后无法捕获auth事件的问题咨询

解决方案

1. 捕获signIn/signUp事件的代码组织方式

第三方登录跳转回应用后,Amplify需要手动处理认证响应才能触发Hub的auth事件,结合SolidJS的生命周期,按以下步骤调整:

步骤1:全局注册Hub监听

在应用根组件的onMount中注册Hub监听,确保监听在Amplify配置完成后立即生效,同时在组件卸载时移除监听:

import { onMount } from 'solid-js';
import { Amplify } from '@aws-amplify/core';
import { Auth, Hub } from '@aws-amplify/auth';
import awsconfig from './aws-exports';

// 初始化Amplify配置
Amplify.configure(awsconfig);

const App = () => {
  onMount(() => {
    // 注册auth事件监听
    const authUnsubscribe = Hub.listen('auth', ({ payload }) => {
      const { event, data } = payload;
      switch (event) {
        case 'signIn':
          console.log('登录成功:', data);
          // 执行登录后的业务逻辑
          break;
        case 'signUp':
          console.log('注册成功:', data);
          // 执行注册后的业务逻辑
          break;
        case 'signOut':
          console.log('登出成功');
          break;
        default:
          break;
      }
    });

    // 组件卸载时取消监听
    return () => authUnsubscribe();
  });

  // 路由、页面内容等
  return <div>你的应用内容</div>;
};

export default App;

步骤2:在回调页面处理认证响应

在第三方登录返回的回调页面(/account/external)中,调用Auth.handleAuthResponse()处理授权码,完成会话初始化,此时Hub会触发signIn事件:

import { onMount } from 'solid-js';
import { Auth } from '@aws-amplify/auth';

const ExternalCallback = () => {
  onMount(async () => {
    try {
      // 处理第三方登录返回的URL参数
      await Auth.handleAuthResponse(window.location.href);
      // 处理完成后跳转至目标页面(如用户中心)
      window.location.href = '/dashboard';
    } catch (err) {
      console.error('认证响应处理失败:', err);
      // 处理错误逻辑,如跳转至登录页
      window.location.href = '/login';
    }
  });

  return <div>正在处理登录,请稍候...</div>;
};

export default ExternalCallback;

关键配置注意

确保aws-exports.js中的OAuth配置正确指向回调页面:

export default {
  // 其他Amplify配置
  oauth: {
    domain: '你的Cognito域名.auth.区域.amazoncognito.com',
    scope: ['email', 'openid', 'profile'],
    redirectSignIn: 'https://你的域名/account/external',
    redirectSignOut: 'https://你的域名/',
    responseType: 'code',
    urlOpener: (url, redirectUrl) => window.open(url, '_blank')
  }
};

注:原页面因跳转至第三方认证页会处于后台,无法捕获新标签页的认证事件,回调页处理完成后跳转的新页面会触发Hub的signIn事件。

2. 关联登录发起数据与CognitoUser的实现方式

Amplify的Auth.federatedSignIn不支持直接传递自定义数据到Hub事件,但可以通过本地临时存储的方式实现关联:

步骤1:登录发起时存储自定义数据

在调用federatedSignIn前,将需要关联的数据存入sessionStorage(会话结束自动清除,比localStorage更安全):

import { Auth, CognitoHostedUIIdentityProvider } from '@aws-amplify/auth';

const SignUp = () => {
  const handleGoogleLogin = async () => {
    // 存储需要关联的已有用户ID等数据
    sessionStorage.setItem('authAssocData', JSON.stringify({ existingUserId: '用户ID' }));
    await Auth.federatedSignIn({ provider: CognitoHostedUIIdentityProvider.Google });
  };

  return <button onClick={handleGoogleLogin}>绑定Google账号</button>;
};

export default SignUp;

步骤2:在Hub事件中读取并关联数据

在Hub的signIn事件监听中,读取临时存储的数据,完成关联后删除:

Hub.listen('auth', ({ payload }) => {
  if (payload.event === 'signIn') {
    const assocDataStr = sessionStorage.getItem('authAssocData');
    if (assocDataStr) {
      const assocData = JSON.parse(assocDataStr);
      // 关联Cognito用户与已有用户数据,比如调用后端API完成绑定
      console.log('绑定用户:', payload.data.username, assocData.existingUserId);
      // 用完后清除临时数据
      sessionStorage.removeItem('authAssocData');
    }
  }
});

注:避免在本地存储中存放敏感数据,若需更高安全性,可结合后端生成的临时令牌替代明文数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:10:49