AWS Cognito:重试的自定义挑战

Ras*_*adi 4 amazon-web-services amazon-cognito aws-lambda

我对 MFA 使用自定义挑战,因为我想使用 Twilio 而不是 AMAZON SNS。我已经成功地实施了它。它工作正常,但是当用户输入错误的 OTP 代码时。用户会话已过期。意味着他必须再次提供电话号码并再次请求 OTP。而我希望它至少重试 3 次。在他需要请求另一个 OTP 之前。我的响应验证触发器如下所示,我们可以做些什么。

(event, context, callback) => {
    if (event.request.privateChallengeParameters.answer == event.request.challengeAnswer) {
        event.response.answerCorrect = true;
    } else {
        event.response.answerCorrect = false;
    }
    callback(null, event);
}
Run Code Online (Sandbox Code Playgroud)

Bre*_*ith 7

我通过将答案作为变量添加到challengeMetaData 中来实现这一点——据我所知,它没有返回给客户端,但在后续调用中可用,我还有一个名为尝试的变量,用于跟踪用户输入了多少次不正确的值。我的代码如下 - 我希望它有帮助

const AWS = require("aws-sdk");
exports.handler = (event, context, callback) => {

    const session = event.request.session;
    const currentSession = session ? session.length - 1 : 0

    switch (event.triggerSource) {
        case 'DefineAuthChallenge_Authentication':

            console.log("DefineAuthChallenge_Authentication");
            console.log(event);

            if (session.length === 0) {
                event.response = {
                    challengeName: 'CUSTOM_CHALLENGE',
                    failAuthentication: false,
                    issueTokens: false
                };
            }
            else {
                if (session[currentSession].challengeName === 'CUSTOM_CHALLENGE') {

                    if (session[currentSession].challengeResult === true) {
                        event.response.issueTokens = true;
                        event.response.failAuthentication = false;
                    }
                    else {

                        let metaData = JSON.parse(session[currentSession].challengeMetadata);
                        if (metaData.attempts <= 3) {
                            event.response = {
                                challengeName: 'CUSTOM_CHALLENGE',
                                failAuthentication: false,
                                issueTokens: false
                            };
                        }
                        else {
                            event.response.issueTokens = false;
                            event.response.failAuthentication = true;
                        }
                    }
                }
            }
            console.log(event);
            break;
        case 'CreateAuthChallenge_Authentication':
            if (event.request.challengeName === 'CUSTOM_CHALLENGE') {
                console.log("CreateAuthChallenge_Authentication");
                console.log(event);
                if (session.length === 0) {
                    let answer = Math.random().toString(10).substr(2, 6);

//Your logic to send a message goes here
                    
                    event.response.publicChallengeParameters = { challengeType: 'SMS_CODE' };
                    event.response.privateChallengeParameters = { answer: answer };
                    event.response.challengeMetadata = JSON.stringify({ '_sid': answer, 'challengeType': 'SMS_CODE', attempts: 1 });
                }
                else {
                    let metaData = JSON.parse(session[currentSession].challengeMetadata);
                    if (metaData.attempts <= 3) {
                        event.response.publicChallengeParameters = { challengeType: 'SMS_CODE', errorCode: 'NotAuthorizedException' };
                        event.response.privateChallengeParameters = { answer: metaData._sid };
                        event.response.challengeMetadata = JSON.stringify({ '_sid': metaData._sid, 'challengeType': 'SMS_CODE', attempts: metaData.attempts + 1 });
                    }
                }
            }
            console.log(event);
            break;
        default:
            console.log("VerifyAuthChallenge_Authentication");
            console.log(event);
            if (event.request.privateChallengeParameters.answer === event.request.challengeAnswer) {
                event.response.answerCorrect = true;
            }
            else { event.response.answerCorrect = false; }
            console.log(event);
            break;
    }
    callback(null, event);
};
Run Code Online (Sandbox Code Playgroud)

  • @TurbutAlin:关键是在第一次错误尝试后重新启动会话。如果仔细观察, event.session 是一个数组,当多个会话过期时,它会不断获取它们。您可以重新启动一个新会话并再次在内部运行整个流程。然而,唯一的缺点是,当在同一周期中重新启动会话时,您会得到一个新的会话对象,并且不会明确得到错误对象。 (2认同)