Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't resend verification code through AWS Cognito API

I have an AWS Cognito User Pool where users are created through Cognito's API using the AdminCreateUser action, which works fine. This sends out a verification e-mail to the user, containing a temporary password. So far so good.

Now a user did not receive this verification e-mail, so I need to send it again, using the ResendConfirmationCode action. I am attempting to do that with the below PHP code.

$userPoolId = '[POOL_ID_HERE]';
$backendAppId = '[APP_ID_HERE]';
$clientSecret = '[SECRET_HERE]';
$username = '[UUID_HERE]';

$secretHash = base64_encode(hash_hmac('sha256', $username . $backendAppId, $clientSecret, true));

$cognitoIdp->resendConfirmationCode([
    'ClientId' => $backendAppId,
    'SecretHash' => $secretHash,
    'Username' => $username,
]);

That gives me the following error:

Aws/CognitoIdentityProvider/Exception/CognitoIdentityProviderException with message 'Error executing "ResendConfirmationCode" on "https://cognito-idp.eu-central-1.amazonaws.com"; AWS HTTP error: Client error: POST https://cognito-idp.eu-central-1.amazonaws.com resulted in a 400 Bad Request response: {"__type":"NotAuthorizedException","message":"Can't resend confirmation code for this user"} NotAuthorizedException (client): Can't resend confirmation code for this user - {"__type":"NotAuthorizedException","message":"Can't resend confirmation code for this user"}'

I am using the credentials of a user which has the following IAM permissions for the user pool:

  • cognito-idp:AdminDeleteUser
  • cognito-idp:AdminCreateUser
  • cognito-idp:AdminAddUserToGroup
  • cognito-idp:ResendConfirmationCode

If I test the permissions using the IAM Policy Simulator, it gives me the green light, saying that everything is OK. To my knowledge, the cognito-idp:ResendConfirmationCode action should be sufficient, as sending out the verification e-mail works fine when creating the user.

What am I doing wrong here? An alternative approach would be to invoke the AdminCreateUser action again, setting the MessageAction parameter to RESEND. This would force the verification e-mail to be resent for existing users, but I prefer using the ResendConfirmationCode action if I can get it to work.

Any ideas? Thanks!

like image 502
ba0708 Avatar asked Mar 06 '23 03:03

ba0708


1 Answers

I understand that you would like your web application end users to receive a confirmation code again if they do not get the confirmation code due to some reason after they sign-up, and I also understand that you are getting the "NotAuthorizedException" when you are trying to run the ResendConfirmationCode API call from your code that uses the PHP SDK.

The ResendConfirmationCode API call[1] can be used after the sign-up API call[2], and it is not a part of the AdminCreateUser Authentication flow, which is why the error is thrown. The AdminCreateUser API call changes the status of the new user to the "Force Change Password State", and neither the ResendConfirmationCode call or the ForgotPassword call can work after AdminCreateUser is used for creating a new user.

If you would like your end-users to get the confirmation code again, you could use the AdminCreateUser API call itself and set the "RESEND" flag in MessageAction in the PHP code. There would be no other way to send the verification message again in this particular use-case, as per my understanding of Amazon Cognito. An example of the API call in PHP according to the official documentation is as follows[3]:

$result = $client->adminCreateUser([
    'DesiredDeliveryMediums' => ['<string>', ...],
    'ForceAliasCreation' => true || false,
    'MessageAction' => 'RESEND|SUPPRESS',
    'TemporaryPassword' => '<string>',
    'UserAttributes' => [
        [
            'Name' => '<string>', // REQUIRED
            'Value' => '<string>',
        ],
        // ...
    ],
    'UserPoolId' => '<string>', // REQUIRED
    'Username' => '<string>', // REQUIRED
    'ValidationData' => [
        [
            'Name' => '<string>', // REQUIRED
            'Value' => '<string>',
        ],
        // ...
    ],
]);

After using setting 'MessageAction' as 'RESEND', the end-users should be able to receive the verification message again on their end.

References

[1]. https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/resend-confirmation-code.html

[2]. https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/sign-up.html

[3]. https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-cognito-idp-2016-04-18.html#admincreateuser

like image 196
Arka Mukherjee Avatar answered Mar 15 '23 12:03

Arka Mukherjee