Cognito在通过电话确认之前更改phone_number

时间:2017-09-13 09:02:39

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

我想在通过手机确认之前更改用户的phone_number属性。我的流程步骤:

  1. 用户通过用户名,密码和电话号码进行注册

  2. 用户必须输入手机收到的确认码。在此步骤中,用户想要更改电话号码(错误号码或更换电话......)

  3. 2.1如果第一个电话号码错误,下一个电话号码是正确的 - >只发送了一个确认码 - >它有效!

    2.2如果第一个电话号码和下一个电话号码正确 - >已经发送了两个确认码(1st - xxx,2nd - yyy) - >用户输入第二个确认的代码,Cognito throw CodeMismatchException: Invalid verification code provided, please try again.错误。用户输入第一个代码,用户已经确认,但在Cognito系统中,用户phone_number是第二个号码,phone_number_verifiedtrue

    我使用adminUpdateUserAttributes更改状态为phone_number的用户UNCONFIRMED。在我拨打更改电话号码后,确认码自动发送。

    如何解决这个问题?

    !!!更新

    目前,我从应用程序中删除了功能User can update their phone_number before they confirmed via phone

    这需要我大约5天,我只是想记住我的情况。

    当您尝试更新phone_number(或email)属性时,Cognito会自动向您的手机(或电子邮件)发送确认信息,这是第一个代码 - (1st - xxx),用于确认新属性值的代码(不是用户确认)。

    同时,逻辑代码调用resendConfirmationCode函数,它发送第二个代码 - (2nd-yyy),这是主要原因只有第二个代码工作(我们使用confirmSignUp函数来处理代码)。

3 个答案:

答案 0 :(得分:1)

此问题是在不久前提出的,但有些人仍然遇到验证码发送问题,无法验证尚未确认的帐户代码,因此我找到了适用于我们的解决方案。

我们的身份验证流程是:

SignUp -> OTP Screen -> Confirmed OTP -> Cognito Account confirmed -> Custom email sent to user to verify email address -> Update attribute email_verified = true

在OTP屏幕上,我们显示已发送的OTP号码,如果号码不正确,我们允许用户返回注册页面并更改号码并重新提交注册。我们在cognito上为用户使用UUID,以便允许用户再次注册,而不会在帐户已存在但未确认的情况下导致错误。

这意味着我们在Cognito中获得两个UUID帐户,一个被确认,一个未经证实,帐户中唯一的区别是电话号码。然后我们在一段时间后摆脱未经证实的帐户。例如7天

答案 1 :(得分:0)

我在Cognito团队,与behrooziAWS一样。在查看您的场景后,它似乎确实是我们方面的错误。我将在团队中提及它,以便我们相应地优先考虑它。

答案 2 :(得分:0)

对于寻求答案的其他人,我最终要做的是编写一个lambda,该lambda本质上检查用户是否未经确认,删除用户,然后再次注册。我本来是使用updateUserAttributes路由的,但是如果一个坏演员访问了lambda并将更新的已确认用户的电话号码更新为他们的电话,那感觉就很不安全。如果一个用户使用不同的用户名注册但来自另一个帐户的号码相同,则它将使其他用户帐户无效。因此,下面的逻辑。

try {
            const userParams = {
                UserPoolId: process.env.userpool_id,
                Username: event.args.username
            };
            const { UserStatus } = await identity.adminGetUser(userParams).promise();
            if (UserStatus === 'UNCONFIRMED') {
                const deletedIdentity = await identity.adminDeleteUser(userParams).promise();
                if (deletedIdentity) {
                    const signupParams = {
                        ClientId: process.env.client_id,
                        Password: event.args.password,
                        Username: event.args.password,
                        UserAttributes: [
                            {
                                Name: 'phone_number',
                                Value: event.args.phoneNumber
                            }
                        ]
                    }
                    const newSignUp = await identity.signUp(signupParams).promise();
                    if (newSignUp) {
                        response.send(event, context, response.SUCCESS, {
                            newSignUp
                        });
                        callback(null, newSignUp)
                    }
                }
            } else {
                response.send(event, context, response.ACCESSDENIED, {
                    error: 'User not authorized to perform this action'
                });
                callback({error: 'User not authorized to perform this action'}, null)
            }

        } catch (error) {
            response.send(event, context, response.FAILURE, {
                error
            });
            callback(error, null)
        }