如何设置AWS Cognito TOTP MFA?

我正在尝试使用AWS Cognito设置MFA身份验证,作为工作项目的一个小的概念验证。我已经设法获得了用户名和密码,并通过短信发送了MFA代码,工作正常。

正在努力获取用例27使用我的小型登录应用程序中所示的TOTP方法-https://www.npmjs.com/package/amazon-cognito-identity-js

我已修改AssociateSecretCode,以便它向我显示密码,然后进入我的验证器应用程序,但当我尝试使用有效用户登录时,该密码不会显示。

我做错了什么?

以下是我的代码:

<body>
<form>

<ul class="form-style-1">
    <li><label>UserID <span class="required">*</span></label><input type="text" name="username" class="field-divided" placeholder="UID" /></li>
    <li><label>Password <span class="required">*</span></label><input type="password" name="password" class="field-divided" placeholder="Password" /></li>    
    <li>
        <input type="submit" value="Submit" />
    </li>
</ul>
</form>
<div id="results" class="form-style-1"></div>
</body>
</html>
<script type="text/javascript">
//var dataResult;
$(document).ready(function() {

    $('form').submit(function(event) {
    
        
        //-------------------user pool
        AWSCognito.config.region = 'eu-west-2';
     
        var poolData = {
            UserPoolId : 'user pool id here', 
            ClientId : 'app client id here'
        };
        var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
        
        //------------------Authentication-------------------------
        var userData = {
            Username : $('input[name=username]').val(), // your username here
            Pool : userPool
        };
        var authenticationData = {
            Username : $('input[name=username]').val(), // your username here
            Password : $('input[name=password]').val(), // your password here
        };
        var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);

        var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
        cognitoUser.authenticateUser(authenticationDetails, {
        
            
            onSuccess: function(result) {
                console.log('OnSuccess')
                var accessToken = result.getAccessToken().getJwtToken();
                cognitoUser.associateSoftwareToken(this);
            },

            onFailure: function(err) {
                console.log('onFailure')
                alert(err.message || JSON.stringify(err));
            },

            mfaSetup: function(challengeName, challengeParameters) {
                console.log('mfaSetup')
                cognitoUser.associateSoftwareToken(this);
            },

            associateSecretCode: async secretCode => {
                console.log("SECRET CODE: ", secretCode);
                $('#results').html(secretCode);
                
                setTimeout(() => {
                  const challengeAnswer = prompt("Please input the TOTP code.", "");
                  cognitoUser.verifySoftwareToken(challengeAnswer, "My TOTP device", {
                    onSuccess: session => console.log("SUCCESS TOTP: ", session),
                    onFailure: err => console.error("ERROR TOTP: ", err)
                  });
                }, 2000);
            },

            selectMFAType: function(challengeName, challengeParameters) {
                console.log('selectMFAType')
                var mfaType = prompt('Please select the MFA method.', ''); // valid values for mfaType is "SMS_MFA", "SOFTWARE_TOKEN_MFA"
                cognitoUser.sendMFASelectionAnswer(mfaType, this);
            },

            totpRequired: function(secretCode) {
                console.log('totpRequired')
                var challengeAnswer = prompt('Please input the TOTP code.', '');
                cognitoUser.sendMFACode(challengeAnswer, this, 'SOFTWARE_TOKEN_MFA');
            },

            mfaRequired: function(codeDeliveryDetails) {
                console.log('mfaRequired')
                var verificationCode = prompt('Please input verification code', '');
                cognitoUser.sendMFACode(verificationCode, this);
            }
        });
    });
});
</script>

解决方案

我找到的最佳解决方案是使用Amplify UI组件。您不需要使用Amplify的所有其余部分,只需获取两个相关的JS库,导入、配置,然后将所需的页面包装在withAuthenticator组中。默认设置通过软件和短信TOTP处理注册和质询,以及忘记密码和创建帐户流。您所期望的所有错误处理都包括在内,甚至包括语言/主题定制和本地化。非常全面。

虽然计算起来很痛苦,但假设您已经设置了Cognito User Pool,那么这些步骤实际上一点也不复杂。(注意:Amplify需要不使用客户端机密的用户池客户端。)

您可以在my answer中找到类似的StackOverflow问题的示例代码。

相关文章