3

I am trying to make a custom authentication flow using AWS Cognito so that i can send MFA codes via email instead through the cognito triggers. I am using the initiateAuth() method to do this which is correct according to the documentation;

https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#initiateAuth-property

My payload seems to be valid but when i try login with a user i get the error 't.getauthparameters is not a function'

I've had a look through some other stackoverflow posts but nothing is helping

Any ideas what is going wrong?

This is a snippet from my code below:


const payload = {
          AuthFlow: 'CUSTOM_AUTH',
          ClientId: 'my client id', 
          AuthParameters: {
             USERNAME: $('input[name=username]').val(),
             PASSWORD: $('input[name=password]').val(),
             CHALLENGE_NAME: 'SRP_A'
          }
        };
        
        cognitoUser.initiateAuth(payload, {
            onSuccess: function(result) {
                // User authentication was successful
            },
            onFailure: function(err) {
                // User authentication was not successful
            },
            customChallenge: function(challengeParameters) {
                // User authentication depends on challenge response
                var verificationCode = prompt('Please input OTP code' ,'');
                cognitoUser.sendCustomChallengeAnswer(verificationCode, this);
            },
        });
dynamo
  • 184
  • 13

3 Answers3

4

So i ended up finding out that initiateAuth() is not the correct method to use.

The right method to use is cognitoUser.authenticateUser() (since i am using SRP-based authentication then adding a custom challenge) - My updated code is below

This was a similar example that i followed to help me find the answer

I couldnt find very much online for doing it with just the Amazon Cognito Identity SDK so hopefully this is helpful for anyone doing the same!

AWSCognito.config.region = 'region';
        
        var poolData = {
            UserPoolId : 'user pool id', 
            ClientId : 'client id' 
        };
        var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
        
        var userData = {
            Username: $('input[name=username]').val(),
            Pool: userPool,
        };
        var authenticationData = {
            Username : $('input[name=username]').val(),
            Password : $('input[name=password]').val(),
        };

        var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
        var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
        
        cognitoUser.setAuthenticationFlowType('CUSTOM_AUTH');
        
        cognitoUser.authenticateUser(authenticationDetails, {
            onSuccess: function(result) {
                console.log('success');
                var resultStr = 'Login Successful';
                console.log(resultStr);
                $('#resultsSignIn').html(resultStr);
            },
            onFailure: function(err) {
                alert(err);
            },
            customChallenge: function(challengeParameters) {
                // User authentication depends on challenge response
                var verificationCode = prompt('Please input OTP code' ,'');
                cognitoUser.sendCustomChallengeAnswer(verificationCode, this);
            },
        });
        
        return false;`
dynamo
  • 184
  • 13
  • Thanks a lot for posting your answer on this. It saved me a lot of time. One thing is missing to me though: Where this code goes in? Which lambda trigger? pre-authentication lambda function? – salouri Oct 31 '22 at 11:16
  • 1
    @salouri Hey, so this code doenst go into any lambda trigger. This is the code that calls your Custom Cognito function so this code was used alongside my login page. Hope this helps. – dynamo Nov 01 '22 at 13:25
  • I need to intercept the cognito login step to find if it failed or not. I can't find a Cognito Lambda trigger for this (post-authentication: after the login. pre-authentication: before the login). Any idea how to catch failed logins? – salouri Nov 03 '22 at 07:58
  • https://github.com/cammyyp/Cognito-email-mfa this is my solution here - it has all the lambda triggers code as well as the config – dynamo Nov 03 '22 at 13:07
  • thank you, cognitoUser.setAuthenticationFlowType('CUSTOM_AUTH'); this line is the key, it works fine now – Kannan T Sep 01 '23 at 12:43
1

A downside to the authenticateUser() method is that you won't be able to get user's input mid-execution during the authenticateUser workflow (i.e, having to use prompts in the callbacks for customchallenge etc). I believe initiateAuth() would solve this issue.

https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-define-auth-challenge.html

javabroom
  • 61
  • 2
  • Do you know where this code is supposed to live in? Which lambda trigger? pre-authentication lambda function? – salouri Oct 31 '22 at 11:16
0

Long time back, I encountered the same issue and discovered a solution that worked. Instead of using the regular initiateAuth, I made the switch to adminInitiateAuth. This admin method allows you to initiate authentication on behalf of the user.

Here's the code snippet:

customChallenge: async () => {
  try {
    const data = await identityProvider.adminInitiateAuth(initiateAuthParams);
    resolve({ challengeName: data.ChallengeName });
  } catch (err) {
    reject(err);
  }
};
starball
  • 20,030
  • 7
  • 43
  • 238
Mona
  • 11
  • 1