我正在尝试使用他们的Go SDK
实现构建在Cognito
上的身份验证。我已经能够让基本的username/password
身份验证工作,但是当我使用SMS
添加双因素身份验证时,我就卡住了。
重现步骤:
1.我使用用户名/密码和电子邮件验证创建用户
1.我验证电子邮件地址
1.我设置了电话号码并请求验证码
1.我核实了电话号码
1.我启用了双重身份验证(通过短信)
1.我尝试登录并接收SMS_MFA挑战
1.我在手机上收到该代码,并呼叫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文档和无用的错误让我抓狂,所以任何帮助都将不胜感激!
谢谢.
2条答案
按热度按时间mm5n2pyu1#
你的问题似乎模棱两可。
第二步你是
1.我设置了电话号码并请求验证码
1.我核实了电话号码
如果你已经正确配置了这个池,这就是Cognito中的MFA。
你不能既有手机登录和MFA。这没有意义。
但如果你有手机登录,那么Cognito将发送短信每次与代码。密码是只用于电子邮件登录。
rqcrx0a62#
经过大量的挖掘和浏览amplify/cognito js repos中的开放问题,我找到了这个解决方案。
在接收到作为SMS的代码后,不要再次触发/调用身份验证流程以发送SMS MFA代码,这会导致代码无效,并且在收到错误后,您可能会注意到另一个SMS MFA代码正在发送,这是由于最后一次身份验证调用发送初始SMS MFA代码。
相反,创建另一个路径或方法,您可以在其中使用
adminRespondToAuthChallenge
或sendMFACode
,前提是Session
参数必须具有上次authenticate调用的session值。我使用的是JS包而不是Go,但逻辑必须相同。在我的例子中,我构建了REST API,它在Lambda中调用authenticate函数。
authenticate
函数在用户提交邮箱和密码后被调用。字符串
sendSMSMFA
Lambda函数,用户在前端输入代码后调用型
在开放问题的某个地方,我读到了一个功能请求,它专门要求一个验证SMS MFA代码并返回令牌的函数,但在此之前,我认为这是一个笨拙的方法。
对于任何人谁想知道为什么这是不发生时,使用TOTP软件令牌方法是因为MFA代码时钟是独立的认知时钟,因此将始终有一个同步,即使代码发送在不同的
authenticate
调用,但短信MFA是真正依赖于会话ID.