Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

423
Views
AWS Amplify: How to map social providers attributes for an email based authentication?

I have a React web application built with AWS Amplify I have added authentication with Cognito user pools, I am not using usernames, I have selected the login using email/phone only, I don't want usernames, but Cognito creates a random username anyway.

I want that the user to login using their email or using one social provider (Facebook or Google) and it shouldn't matter, they should have access to the same account, based on the email.

Pretty normal practice, I think. However, when I first tried to log in with a social provider I noticed that instead of Cognito gives me the same account, it created a new one, with a different username and with EXTERNAL_PROVIDER as account status on the user pool

So, I thought it might be just some mapping being made incorrectly, I went to the Attributes mapping on the Federation section, and I saw that the Facebook Id and Google Sub were being assigned to the username, I tried to remove it and for my surprise, it was assigned back to the username. Then I thought "I can just create a custom attribute to store that information and it should be fine".

So I did this, created one attribute for Facebook, one for GoogleId... tried again...nope, still getting back to username, but no error message, nothing...

I went for help on the documentation and found this

Currently, only the Facebook id, Google sub, login with Amazon user_id, and Sign in with Apple sub attributes can be mapped to the Amazon Cognito User Pools username attribute.

If this always associate each provider Id with the username, then, there's no way to merge those accounts I thought it could be that I need to setup a federated identity pool, but reading about it it seems that it is used to give IAM roles/permission to the external users, which I don't want to.

Any idea of how can I achieve that?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

After digging a bit into it, I found the solution. In summary, you should:

  • Create a trigger on Cognito for the Pre-Signup to a lambda function
  • This lambda function should find the corresponding account and link both users
  • Return the event from the lambda function

You can create the trigger from Amplify cli, running amplify auth update, doing the "Walkthrough all the auth configurations", in the end, it is gonna ask you if you want to create the trigger, confirm it and select the Pre Signup Trigger

Then edit the function file created, the default runtime is nodejs, I have changed mine to Python

This is the code I'm using

import boto3

client = boto3.client('cognito-idp')


def handler(event, context):
    print("Event: ", event)
    email = event['request']['userAttributes']['email']

    # Find a user with the same email
    response = client.list_users(
        UserPoolId=event['userPoolId'],
        AttributesToGet=[
            'email',
        ],
        Filter='email = "{}"'.format(email)
    )

    print('Users found: ', response['Users'])

    for user in response['Users']:
        provider = None
        provider_value = None
        # Check which provider it is using
        if event['userName'].startswith('Facebook_'):
            provider = 'Facebook'
            provider_value = event['userName'].split('_')[1]
        elif event['userName'].startswith('Google_'):
            provider = 'Google'
            provider_value = event['userName'].split('_')[1]

        print('Linking accounts from Email {} with provider {}: '.format(
            email,
            provider_value
        ))

        # If the signup is coming from a social provider, link the accounts
        # with admin_link_provider_for_user function
        if provider and provider_value:
            print('> Linking user: ', user)
            print('> Provider Id: ', provider_value)
            response = client.admin_link_provider_for_user(
                UserPoolId=event['userPoolId'],
                DestinationUser={
                    'ProviderName': 'Cognito',
                    'ProviderAttributeValue': user['Username']
                },
                SourceUser={
                    'ProviderName': provider,
                    'ProviderAttributeName': 'Cognito_Subject',
                    'ProviderAttributeValue': provider_value
                }
            )
    # Return the event to continue the workflow
    return event
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!