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

通过Google登录Cognito后调用getSession获取会话失败求助

问题描述

在React项目中使用amazon-cognito-identity-js库配置Cognito Google授权登录,用户已成功在用户池中创建。通过以下代码跳转至Cognito托管登录页完成Google登录:

const path = `https://${myDomain}.auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=${clientId}&redirect_uri=${redirect}`;
router.push(path);

登录成功重定向回应用后,调用以下代码尝试获取用户会话时,MyPool.getCurrentUser()返回undefined,触发错误Current user not found:

const getSession = (role: TRoles): Promise<IReturnObj> => {
  return new Promise((resolve, reject) => {
    const user = MyPool.getCurrentUser();

    if (!user) {
      reject(new Error('Current user not found'));
    }

    user.getSession((err: Error, session: CognitoUserSession) => {
      if (err) {
        reject(err);
      } else {
        resolve({session, user});
      }
    });
  });
};

Cognito应用客户端设置截图:
Cognito应用客户端设置

问题原因及解决步骤

核心问题是:使用授权码流程(response_type=code)跳转登录后,重定向回应用时未处理Cognito返回的授权码,未完成令牌交换并初始化CognitoUser实例,导致getCurrentUser()无法从本地存储读取到用户数据。

1. 处理重定向后的授权码

重定向回应用时URL会携带code参数,需用该授权码交换令牌并完成用户初始化,推荐用amazon-cognito-identity-js内置的CognitoAuth类处理:

import { CognitoAuth } from 'amazon-cognito-identity-js';

const authData = {
  ClientId: clientId,
  AppWebDomain: `${myDomain}.auth.us-east-1.amazoncognito.com`,
  TokenScopesArray: ['openid', 'email', 'profile'], // 根据需求调整权限范围
  RedirectUriSignIn: redirect,
  RedirectUriSignOut: '你的退出重定向地址'
};

const auth = new CognitoAuth(authData);

auth.userhandler = {
  onSuccess: (result) => {
    // 登录成功后Cognito自动将用户数据存入本地存储,此时可调用getSession
    getSession(role).then(res => {
      // 处理会话和用户属性
    });
  },
  onFailure: (err) => {
    console.error('登录失败', err);
  }
};

// 在重定向后的页面初始化时调用,解析Cognito返回的授权码
auth.parseCognitoWebResponse(window.location.href);

2. 检查应用客户端配置

从截图确认以下配置:

  • 重定向URI(redirect_uri)与Cognito应用客户端中配置的完全一致,包括协议、域名、路径,不能有任何差异
  • 取消勾选Generate client secret(前端应用无法安全存储密钥,授权码流程下无需启用)

3. 手动令牌交换与用户初始化(可选)

若不想用CognitoAuth,可手动处理令牌交换并创建CognitoUser实例:

// 从URL中提取授权码
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');

// 发送请求交换令牌
fetch(`https://${myDomain}.auth.us-east-1.amazoncognito.com/oauth2/token`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    client_id: clientId,
    code: code,
    redirect_uri: redirect
  })
})
.then(res => res.json())
.then(data => {
  // 创建CognitoUser实例
  const userData = {
    Username: data.id_token_payload.username, // 从id_token的payload中获取用户名
    Pool: MyPool
  };
  const cognitoUser = new CognitoUser(userData);
  
  // 设置并保存会话
  const session = new CognitoUserSession({
    IdToken: new CognitoIdToken({ IdToken: data.id_token }),
    AccessToken: new CognitoAccessToken({ AccessToken: data.access_token }),
    RefreshToken: new CognitoRefreshToken({ RefreshToken: data.refresh_token })
  });
  
  cognitoUser.setSignInUserSession(session);
  cognitoUser.saveSession(session, (err) => {
    if (!err) {
      // 此时getCurrentUser()可正常获取用户
      getSession(role).then(res => {
        // 处理数据
      });
    }
  });
})
.catch(err => console.error('令牌交换失败', err));

内容的提问来源于stack exchange,提问作者Олег Верушкин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:30:49