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

Amplify集成Cognito时tokenRefresh事件高频重复触发问题

问题背景

使用如下代码监控Amplify+Cognito认证流程:

const handleHubEvent = useCallback((capsule) => {
  const event = capsule?.payload?.event;

  try {
    switch(event){
      case 'signIn_start':
      case 'signIn':
      case 'tokenRefresh':
        const user = await auth.currentAuthenticatedUser();
        setCurrentUser(user);
        break;
      case 'signOut':
      case 'tokenRefresh_failure':
        setCurrentUser(null);
        break;
    }
  } catch (e) {
    console.log("Error: ", e);
    setCurrentUser(null);
  }
}, []);

useEffect(() => {
  Hub.listen('auth', handleHubEvent);
  Hub.dispatch('auth', { event: 'signIn_start' });

  return () => Hub.remove('auth', handleHubEvent);
}, []);

运行后出现异常:

  • 页面运行数小时到达会话过期节点后,事件回调handleHubEvent持续高频触发,频率约每秒7次
  • 浏览器网络面板可观测到大量发往cognito-idp.ap-southeast-2.amazonaws.com的请求
  • 已确认Hub.listen仅执行一次,不存在同一事件绑定多个监听器的情况
  • 刷新页面后异常行为仍然存在,仅删除站点Cookie后重新登录可临时恢复
代码逻辑错误说明

代码存在4处明确问题,直接触发上述高频死循环现象:

  • 基础语法错误:handleHubEvent未声明为async函数,内部直接使用await调用异步方法会抛出语法异常,导致try/catch块、分支内的状态重置逻辑完全失效,异常发生时无法按预期执行兜底逻辑。
  • 事件递归触发逻辑:signIn_start、signIn、tokenRefresh三个事件分支均调用auth.currentAuthenticatedUser(),该方法检测到Access Token过期时会自动执行Token刷新流程,执行过程中会再次向Hub派发tokenRefresh事件,直接形成「回调触发→调用Auth方法→派发新事件→再次触发回调」的无限循环。
  • 无效凭证残留:tokenRefresh_failure分支和catch块仅修改了前端内存中的用户状态,未调用auth.signOut()清理Amplify存储在Cookie、LocalStorage中的无效凭证。页面刷新后Amplify初始化阶段会读取这些残留凭证,反复发起无效的Token刷新请求,这是刷新页面后异常仍不消失的核心原因。
  • 冗余触发逻辑:useEffect挂载时主动dispatch signIn_start事件属于多余操作,Amplify初始化时会自动检测本地凭证状态并派发对应Auth事件,手动触发会在凭证异常场景下放大循环调用的频率。
修复后参考代码
const handleHubEvent = useCallback(async (capsule) => {
  const event = capsule?.payload?.event;

  try {
    switch(event){
      case 'signIn':
      case 'tokenRefresh':
        const user = await auth.currentAuthenticatedUser();
        setCurrentUser(user);
        break;
      case 'signIn_start':
        // 移除该分支的重复调用,避免循环触发
        break;
      case 'signOut':
      case 'tokenRefresh_failure':
        // 主动清理本地无效凭证
        await auth.signOut({ global: false });
        setCurrentUser(null);
        break;
    }
  } catch (e) {
    console.log("Auth handle error: ", e);
    // 异常场景下同步清理凭证
    await auth.signOut({ global: false });
    setCurrentUser(null);
  }
}, []);

useEffect(() => {
  Hub.listen('auth', handleHubEvent);
  // 移除手动dispatch的signIn_start事件,避免重复触发

  return () => Hub.remove('auth', handleHubEvent);
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.11 16:16:22