【问题标题】:AWS Cognito: Custom Challenge with RetryAWS Cognito:重试自定义挑战
【发布时间】:2022-03-22 16:54:36
【问题描述】:

我正在为 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);
}

【问题讨论】:

    标签: amazon-web-services aws-lambda amazon-cognito


    【解决方案1】:

    我通过将答案作为变量添加到 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);
    };

    【讨论】:

    • 我知道你在那里尝试过什么。但是,由于某种原因,我的第二次尝试仍然失败。一次无效尝试后,我的会话已过期,并且我不断收到Invalid session for user 错误。当 otp 尝试小于 3 时,您在 Define Auth Challenge 中的代码没有被我调用...有什么建议吗?
    • 没关系...我想通了。但是,您的解决方案很有帮助。谢谢老兄。
    • @SaurabhTiwari 你解决了什么问题?我遇到了同样的问题,经过一次尝试,我得到了 Invalid session for user。
    • @TurbutAlin:关键是在第一次错误尝试后重新启动会话。如果你仔细观察,event.session 是一个数组,当它们过期时会不断获得多个会话。您可以重新启动一个新会话并再次在内部运行整个流程。然而,唯一的缺点是,当会话在同一个周期中重新启动时,您将获得一个新的会话对象,并且明确地没有错误对象。
    • 在来自@Brett 的上述代码中,请注意,当他在DefineAuthChallenge 中比较尝试
    猜你喜欢
    • 2022-08-03
    • 2019-08-11
    • 2018-11-13
    • 1970-01-01
    • 2021-03-21
    • 2012-05-14
    • 2011-08-12
    • 2021-07-12
    • 1970-01-01
    相关资源
    最近更新 更多