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; };
工作流程
- 用户点击重发按钮,前端发送
challengeAnswer: 'Dummyval'到Cognito的respondToAuthChallenge接口 VerifyAuthChallenge识别到该值,设置answerCorrect: false并标记challengeMetadata: 'RESEND_CODE',返回结果给Cognito- Cognito再次触发
CreateAuthChallenge,此时session长度大于2,读取到上一次的重发标记,生成新验证码并发送邮件 - 新验证码被传递到前端,用户可输入新验证码完成验证
内容的提问来源于stack exchange,提问作者Kannan T
相关产品推荐
相关产品推荐

