如何设置 AWS Cognito TOTP MFA?

How to setup 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 HOC 中。默认设置使用软件和 SMS TOTP 处理注册和质询,以及忘记密码和创建帐户流程。包括您期望的所有错误处理,甚至 language/theme 自定义和本地化。很全面。

虽然很难理解,但假设您已经设置了 Cognito 用户池,这些步骤实际上一点也不复杂。 (注意:Amplify 需要一个 使用客户端密钥的用户池客户端。)

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