我正在使用Cognito用户池来验证我的Web应用程序。我现在一切正常,但是现在我需要为其启用MFA。我现在就是这样做的(提供的所有代码都是服务器端代码):
const cognito = new AWS.CognitoIdentityServiceProvider();
cognito.signUp({
ClientId,
Username: email,
Password,
}).promise();
带有内部代码的电子邮件将发送到用户的地址(在上一个函数调用中称为用户名)。
用户读取代码并将代码提供给下一个函数调用:
cognito.confirmSignUp({
ClientId,
ConfirmationCode,
Username: email,
ForceAliasCreation: false,
}).promise();
const tokens = await cognito.adminInitiateAuth({
AuthFlow: 'ADMIN_NO_SRP_AUTH',
ClientId,
UserPoolId,
AuthParameters: {
'USERNAME': email,
'PASSWORD': password,
},
}).promise();
我对此过程非常满意。但是现在我需要为此添加TOTP MFA功能。有人可以告诉我如何更改这些步骤吗?顺便说一句,我知道创建用户池时需要为用户池启用TOTP MFA。我只是在问它如何影响我的注册/登录过程。
答案 0 :(得分:5)
好的,我自己找到了一种方法。我必须说,我找不到关于此的任何文档,因此,使用后果自负!
当然,此过程假设您有一个启用了MFA的用户池(我使用了TOTP MFA)。
const cognito = new AWS.CognitoIdentityServiceProvider();
cognito.signUp({
ClientId,
Username: email,
Password,
}).promise();
带有内部代码的电子邮件将发送到用户的地址(在上一个函数调用中称为用户名)。
用户读取代码并将代码提供给下一个函数调用:
cognito.confirmSignUp({
ClientId,
ConfirmationCode: code,
Username: email,
ForceAliasCreation: false,
}).promise();
await cognito.adminInitiateAuth({
AuthFlow: 'ADMIN_NO_SRP_AUTH',
ClientId,
UserPoolId,
AuthParameters: {
'USERNAME': email,
'PASSWORD': password,
},
}).promise();
这时,返回值将有所不同(与未执行MFA时得到的返回值相比)。返回值将类似于:
{
"ChallengeName": "MFA_SETUP",
"Session": "...",
"ChallengeParameters": {
"MFAS_CAN_SETUP": "[\"SOFTWARE_TOKEN_MFA\"]",
"USER_ID_FOR_SRP": "..."
}
}
返回的对象是说用户需要登录MFA_SETUP
才能登录(每次用户注册一次)。
cognito.associateSoftwareToken({
Session,
}).promise();
需要上一个呼叫,因为有两个选项,并且通过发出给定的呼叫,您告诉Cognito您希望用户启用TOTP MFA(而不是SMS MFA)。 Session
输入是上一个函数调用返回的一个。现在,这一次它将返回此值:
{
"SecretCode": "...",
"Session": "..."
}
用户必须使用给定的SecretCode
并将其输入“ Google Authenticator”之类的应用中。添加后,该应用将开始显示6位数字,该数字每分钟刷新一次。
验证身份验证器应用程序:
cognito.verifySoftwareToken({
UserCode: '123456',
Session,
}).promise()
Session
输入将是步骤5中返回的字符串,UserCode
是当前在身份验证器应用程序上显示的6位数字。如果成功完成此操作,则将获得以下返回值:
{
"Status": "SUCCESS",
"Session": "..."
}
我没有发现此对象返回的会话有任何用处。现在,注册过程已完成,用户可以登录。
await cognito.adminInitiateAuth({
AuthFlow: 'ADMIN_NO_SRP_AUTH',
ClientId,
UserPoolId,
AuthParameters: {
'USERNAME': email,
'PASSWORD': password,
},
}).promise();
当然,这与步骤4相同。但是其返回值不同:
{
"ChallengeName": "SOFTWARE_TOKEN_MFA",
"Session": "...",
"ChallengeParameters": {
"USER_ID_FOR_SRP": "..."
}
}
这是告诉您要完成登录过程,您需要遵循SOFTWARE_TOKEN_MFA
挑战过程。
cognito.adminRespondToAuthChallenge({
ChallengeName: "SOFTWARE_TOKEN_MFA",
ClientId,
UserPoolId,
ChallengeResponses: {
"USERNAME": config.username,
"SOFTWARE_TOKEN_MFA_CODE": mfa,
},
Session,
}).promise()
Session
输入是第8步返回的数字,mfa
是需要从身份验证器应用读取的6位数字。调用该函数后,它将返回令牌:
{
"ChallengeParameters": {},
"AuthenticationResult": {
"AccessToken": "...",
"ExpiresIn": 3600,
"TokenType": "Bearer",
"RefreshToken": "...",
"IdToken": "..."
}
}