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

AWS Cognito自定义挑战:验证码重发功能实现方案咨询

自定义MFA重发验证码解决方案

问题背景

已基于邮箱验证码实现自定义MFA功能,运行正常。需在前端添加「重发验证码」按钮,点击时生成新的有效验证码,但无法直接触发createAuthChallenge。尝试通过传递保留关键字Dummyval实现,能在VerifyAuthChallenge中获取该关键字,但无法传递到CreateAuthChallenge(修改session数组未成功),需实现仅点击重发按钮时生成新验证码的逻辑。

解决方案思路

核心是通过Cognito的session传递重发指令:在VerifyAuthChallenge中识别重发请求,标记重发状态;CreateAuthChallenge在下一次触发时读取该标记,生成新验证码。

实现步骤

  • 前端点击「重发验证码」时,调用respondToAuthChallenge接口,传入challengeAnswer: 'Dummyval'
  • 修改VerifyAuthChallenge:识别到Dummyval时,设置answerCorrect: false,并通过challengeMetadata传递重发标记
  • 修改CreateAuthChallenge:检查session最后一条记录的challengeMetadata,如果是重发标记则生成新验证码,否则沿用旧逻辑

修改后的代码

VerifyAuthChallenge Lambda

exports.handler = asyncHandler((event) => {
  log.info("event: ", event);
  let expectedAnswer =
    event.request.privateChallengeParameters["verificationCode"];
  let timePeriod = expectedAnswer.substring(6, expectedAnswer.length);
  console.log({ timePeriod }, "Time period");
  expectedAnswer = expectedAnswer.substring(0, 6);
  const currentTime = new Date().getTime();
  const diff = currentTime - timePeriod;
  const seconds = Math.floor((diff / 1000) % 60);
  const minutes = Math.floor(diff / 1000 / 60);
  event.response.answerCorrect = false;

  // 正常验证逻辑
  if (event.request.challengeAnswer === expectedAnswer && minutes <= process.env.otpTimeLimit ) {
    event.response.answerCorrect = true;
  }

  // 处理重发请求:标记重发指令
  if(event.request.challengeAnswer === 'Dummyval') {
    event.response.challengeMetadata = "RESEND_CODE";
  }

  log.info({ event }, "return event");
  return event;
});

CreateAuthChallenge Lambda

exports.handler = async (event) => {
  log.info("event: ", event);
  let verificationCode = "";
  // 首次触发MFA挑战(SRP_A和PASSWORD_VERIFIER之后)
  if (event.request.session.length === 2) {
    verificationCode = await buildCodeAndSendEmail(event);
  } else {
    log.info("Inside else part");
    const previousChallenge = event.request.session.slice(-1)[0];
    // 检查是否为重发请求
    if (previousChallenge.challengeMetadata === "RESEND_CODE") {
      verificationCode = await buildCodeAndSendEmail(event);
    } else {
      // 正常重试场景,复用旧验证码
      verificationCode = previousChallenge.challengeMetadata;
    }
  }

  // 传递验证码给VerifyAuthChallenge
  log.info({ verificationCode }, "verficiation code");
  event.response.privateChallengeParameters = {
    verificationCode: verificationCode,
  };

  // 保存验证码到session供后续调用
  event.response.challengeMetadata = verificationCode;

  return event;
};

工作流程

  1. 用户点击重发按钮,前端发送challengeAnswer: 'Dummyval'到Cognito的respondToAuthChallenge接口
  2. VerifyAuthChallenge识别到该值,设置answerCorrect: false并标记challengeMetadata: 'RESEND_CODE',返回结果给Cognito
  3. Cognito再次触发CreateAuthChallenge,此时session长度大于2,读取到上一次的重发标记,生成新验证码并发送邮件
  4. 新验证码被传递到前端,用户可输入新验证码完成验证

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:10:38