【问题标题】:AWS Cognito's SMS Multi Factor Authentication returns invalid code or auth stateAWS Cognito 的 SMS 多因素身份验证返回无效代码或身份验证状态
【发布时间】:2018-12-31 14:36:54
【问题描述】:

我正在尝试使用他们的 Go SDK 实现基于 Cognito 的身份验证。我已经能够让基本的username/password 身份验证工作,但是当我使用SMS 添加两因素身份验证时,我遇到了困难。

重现步骤:

  1. 我使用用户名/密码和电子邮件验证创建用户
  2. 我验证电子邮件地址
  3. 我设置了电话号码并请求验证码
  4. 我验证电话号码
  5. 我启用 2 因素身份验证(通过 SMS)
  6. 我尝试登录并接收 SMS_MFA 质询
  7. 我在手机上收到验证码并致电 AdminRespondToAuthChallenge

问题,我收到了error

CodeMismatchException: Invalid code or auth state for the user.
status code: 400, request id: 1513894e-8efa-11e8-a8f8-97e5e083c03b

短信验证码肯定是对的,看来肯定是和auth状态有关。

对 Cognito 的调用如下所示:

c.cip.SignUp(&cognitoidentityprovider.SignUpInput{
        ClientId: aws.String(c.clientID),
        Username: aws.String(username),
        Password: aws.String(password),
        UserAttributes: []*cognitoidentityprovider.AttributeType{
            {
                Name:  aws.String("email"),
                Value: aws.String(email),
            },
            {
                Name:  aws.String("name"),
                Value: aws.String(fullName),
            },
        },
    })

c.cip.ConfirmSignUp(&cognitoidentityprovider.ConfirmSignUpInput{
    ClientId:         aws.String(c.clientID),
    Username:         aws.String(username),
    ConfirmationCode: aws.String(code),
})


//Add the phone number
c.cip.AdminUpdateUserAttributes(&cognitoidentityprovider.AdminUpdateUserAttributesInput{
            UserPoolId: aws.String(c.userPoolID),
            Username:   aws.String(username),
            UserAttributes: []*cognitoidentityprovider.AttributeType{
                {
                    Name:  aws.String("phone_number"),
                    Value: aws.String(phoneNumber),
                },
            },
        })

//Request a verification code
c.cip.GetUserAttributeVerificationCode(&cognitoidentityprovider.GetUserAttributeVerificationCodeInput{
    AccessToken:   aws.String(accessToken),
    AttributeName: aws.String("phone_number"),
})

//Verify the phone number
c.cip.VerifyUserAttribute(&cognitoidentityprovider.VerifyUserAttributeInput{
    AccessToken:   aws.String(accessToken),
    AttributeName: aws.String("phone_number"),
    Code:          aws.String(code),
})

//Enable SMS 2-factor auth c.cip.AdminSetUserSettings(&cognitoidentityprovider.AdminSetUserSettingsInput{
    UserPoolId: aws.String(c.userPoolID),
    Username:   aws.String(username),
    MFAOptions: []*cognitoidentityprovider.MFAOptionType{
        &cognitoidentityprovider.MFAOptionType{
            AttributeName:  aws.String("phone_number"),
            DeliveryMedium: aws.String("SMS"),
        },
    },
})

c.cip.AdminInitiateAuth(&cognitoidentityprovider.AdminInitiateAuthInput{
    ClientId:   aws.String(c.clientID),
    UserPoolId: aws.String(c.userPoolID),
    AuthFlow:   aws.String("ADMIN_NO_SRP_AUTH"),
    AuthParameters: map[string]*string{
        "USERNAME": aws.String(username),
        "PASSWORD": aws.String(password),
    },
})

c.cip.AdminRespondToAuthChallenge(&cognitoidentityprovider.AdminRespondToAuthChallengeInput{
        ClientId:      aws.String(c.clientID),
        UserPoolId:    aws.String(c.userPoolID),
        ChallengeName: aws.String("SMS_MFA"),
        Session:       aws.String(session),
        ChallengeResponses: map[string]*string{
            "USERNAME":     aws.String(username),
            "SMS_MFA_CODE": aws.String(code),
        },
    })

执行 GetUser 调用会显示用户的当前状态:

User = {
              Enabled: true,
              MFAOptions: [{
                  AttributeName: "phone_number",
                  DeliveryMedium: "SMS"
                }],
              PreferredMfaSetting: "SMS_MFA",
              UserAttributes: [
                {
                  Name: "sub",
                  Value: "bd2bb8bc-dfe6-4216-829c-5ae975ce24e5"
                },
                {
                  Name: "email_verified",
                  Value: "true"
                },
                {
                  Name: "name",
                  Value: "Ben Vogan"
                },
                {
                  Name: "phone_number_verified",
                  Value: "true"
                },
                {
                  Name: "phone_number",
                  Value: "<redacted>"
                },
                {
                  Name: "email",
                  Value: "<redacted>"
                }
              ],
              UserCreateDate: 2018-07-24 03:29:49 +0000 UTC,
              UserLastModifiedDate: 2018-07-24 04:19:51 +0000 UTC,
              UserMFASettingList: ["SMS_MFA"],
              UserStatus: "CONFIRMED",
              Username: "bd2bb8bc-dfe6-4216-829c-5ae975ce24e5"
            }

我不知道是否有办法查询用户的身份验证状态以便我可以验证。

AWS 文档和无益的错误让我发疯了,因此我们将不胜感激!

谢谢。

【问题讨论】:

  • 在某处读到使用电子邮件作为用户名可能会使其工作。可以试试吗?
  • 在用户池的配置中,我选择了要求用户名是电子邮件地址或电话号码的单选按钮,并在该选项下选择了用户名但是电子邮件地址。所以我相信在我的情况下所有用户名都是电子邮件地址。
  • 嗨,你找到什么了吗?
  • Nope 还没有找到解决方案并有效地搁置它,因为它目前并不重要。最终我会尝试使用基于令牌的 2 因素身份验证,看看是否可行。
  • 在 USERNAME = email 时为我工作,但在等于 cognito Id 时无效。

标签: go aws-cognito


【解决方案1】:

您的问题似乎模棱两可。

第2步你是

  1. 我设置了电话号码并请求验证码
  2. 我验证电话号码

这不过是 Cognito 中的 MFA。如果您已正确配置池。

您不能同时拥有用于登录和 MFA 的手机。那没有意义。

但如果您有手机登录,那么 Cognito 每次都会发送带有代码的短信。密码仅用于电子邮件登录。

【讨论】:

  • 我看不出这个问题有多模棱两可。第 1 步清楚地表明我使用用户名和密码创建了该帐户。我没有手机登录。我显然必须设置电话号码来请求 MFA 的 SMS 验证码,这是我在第 2 步中所做的。是的,它只是 Cognito 中的 MFA,它不起作用。使用 Cognito 已经有一段时间了,我的感觉是它还没有准备好用于生产环境,并且强烈建议阅读本文的任何人不要使用它。除了像这样的随机错误之外,无法备份用户池是一个交易破坏者。
猜你喜欢
  • 2018-01-29
  • 2016-02-21
  • 2016-06-25
  • 1970-01-01
  • 2016-12-22
  • 2021-11-28
  • 2020-12-31
  • 2017-01-02
  • 2018-05-22
相关资源
最近更新 更多