amazon-web-servicesaws-lambdaamazon-cognitocustom-authenticationpassword-less

How to Implement OTP-Passwordless Login Using Either Email or Phone Number in Amazon Cognito?


I have successfully implemented an OTP-passwordless login flow following this tutorial with some adaptations.

When creating a new user in Amazon Cognito, I’m asked to choose between the user’s primary sign-in attribute:

user creation screenshot

I’ve also configured some POSTMAN scripts to run the flow successfully. Here’s the request to initiate the flow:

Request Details:

Current Behavior: I can successfully complete the OTP login flow if:

However, I cannot use both email and phone number interchangeably for a given user, as it depends on the primary sign-in attribute selected at the time of user creation.

Issue: I am trying to implement a flow where either the email or phone number can be used for a single user regardless of the primary sign-in attribute. Currently, this seems to be restricted by the sign-up configuration.

Details: In my implementation, the DefineAuthChallenge Lambda function receives an empty user and the userNotFound attribute set to true in the event request when trying to use the non-primary attribute.

Question: Is it possible to configure Amazon Cognito to allow either email or phone number for OTP-passwordless login for a single user? I couldn’t find any documentation on this specific use case. I found this question but I cannot get anything from this resolution.

Any guidance or references to relevant documentation would be greatly appreciated.

Thank you!


Solution

  • Firstly if this is a client side application that calls Cognito API directly, consider proxying via your own backend.

    Now on the backend, you could use the username or email to lookup users using: ListUsers

    Example request:

    {
     "AttributesToGet": [ "email","phone_number" ],
     "Filter": "<<username|email>>",
     "Limit": number,
     "PaginationToken": "string",
     "UserPoolId": "string"
    }
    

    Expected Response:

    {
    "PaginationToken": "efgh5678EXAMPLE",
    "Users": [
        {
            "Attributes": [
                {
                    "Name": "sub",
                    "Value": "eaad0219-2117-439f-8d46-4db20e59268f"
                },
                {
                    "Name": "email",
                    "Value": "testuser@example.com"
                }
            ],
            "Enabled": true,
            "UserCreateDate": 1682955829.578,
            "UserLastModifiedDate": 1689030181.63,
            "UserStatus": "CONFIRMED",
            "Username": "testuser"
        },
    // TRUNCATED
    

    Now simply use the Username from response to continue with the Authentication.