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

Serverless架构下AWS Cognito登录IdToken返回undefined问题

问题分析与解决方案

问题原因

从返回的响应可以看到,Cognito返回了NEW_PASSWORD_REQUIRED挑战,这说明当前用户是首次登录,或是被管理员要求重置密码,此时认证流程尚未完成,因此不会返回包含IdToken的AuthenticationResult字段,仅会返回Session和挑战参数。

解决方案

需要处理密码重置挑战,完整认证流程分为两步:

  1. 首次调用adminInitiateAuth,若收到NEW_PASSWORD_REQUIRED挑战,将Session和必填属性要求返回给前端,引导用户输入新密码及必填属性(如响应中的nickname)
  2. 前端提交新信息后,调用adminRespondToAuthChallenge完成认证,此时即可获取IdToken

修改后的Lambda代码示例

export async function login(
  event: APIGatewayEvent,
  context: Context
): Promise<APIGatewayProxyResult> {
  const body = JSON.parse(event.body!);
  let { email, password, newPassword, nickname } = body;

  try {
    // 发起初始认证请求
    const authParams = {
      AuthFlow: "ADMIN_NO_SRP_AUTH",
      UserPoolId: "MY_POOL_ID",
      ClientId: "MY_CLIENT_ID",
      AuthParameters: {
        USERNAME: email,
        PASSWORD: password,
      },
    };
    const authResponse = await cognito.adminInitiateAuth(authParams).promise();

    // 处理NEW_PASSWORD_REQUIRED挑战
    if (authResponse.ChallengeName === "NEW_PASSWORD_REQUIRED") {
      // 若前端已提交新密码和属性,直接响应挑战
      if (newPassword && nickname) {
        const challengeParams = {
          UserPoolId: "MY_POOL_ID",
          ClientId: "MY_CLIENT_ID",
          ChallengeName: "NEW_PASSWORD_REQUIRED",
          Session: authResponse.Session,
          ChallengeResponses: {
            USERNAME: email,
            NEW_PASSWORD: newPassword,
            "userAttributes.nickname": nickname
          },
        };
        const challengeResponse = await cognito.adminRespondToAuthChallenge(challengeParams).promise();
        return {
          statusCode: 200,
          headers: { "Access-Control-Allow-Origin": "*" },
          body: JSON.stringify({
            token: challengeResponse.AuthenticationResult?.IdToken,
            expires: challengeResponse.AuthenticationResult?.ExpiresIn,
          }),
        };
      } else {
        // 前端未提交新信息,返回挑战要求
        return {
          statusCode: 200,
          headers: { "Access-Control-Allow-Origin": "*" },
          body: JSON.stringify({
            challenge: "NEW_PASSWORD_REQUIRED",
            session: authResponse.Session,
            requiredAttributes: JSON.parse(authResponse.ChallengeParameters.requiredAttributes)
          }),
        };
      }
    }

    // 正常认证成功,返回Token
    return {
      statusCode: 200,
      headers: { "Access-Control-Allow-Origin": "*" },
      body: JSON.stringify({
        token: authResponse.AuthenticationResult?.IdToken,
        expires: authResponse.AuthenticationResult?.ExpiresIn,
      }),
    };
  } catch (error) {
    return {
      statusCode: 401,
      headers: { "Access-Control-Allow-Origin": "*" },
      body: JSON.stringify({ message: "认证失败", error: error.message }),
    };
  }
}

关键说明

  • 当用户处于首次登录或密码重置状态时,Cognito会触发NEW_PASSWORD_REQUIRED挑战,必须完成该挑战才能获取IdToken
  • 前端需处理两种场景:直接接收返回的Token,或收到挑战后展示表单让用户输入新密码和必填属性
  • 响应挑战时,必须携带之前获取的Session,且需提供requiredAttributes中要求的所有属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 19:38:09