Tengo una aplicación web React creada con AWS Amplify He agregado autenticación con grupos de usuarios de Cognito, no estoy usando nombres de usuario, he seleccionado el inicio de sesión usando solo correo electrónico/teléfono, no quiero nombres de usuario, pero Cognito crea un nombre de usuario aleatorio de todos modos .
Quiero que el usuario inicie sesión con su correo electrónico o con un proveedor de redes sociales (Facebook o Google) y no debería importar, deberían tener acceso a la misma cuenta, según el correo electrónico.
Una práctica bastante normal, creo. Sin embargo, cuando intenté iniciar sesión por primera vez con un proveedor social, noté que, en lugar de que Cognito me diera la misma cuenta, creó una nueva, con un nombre de usuario diferente y con EXTERNAL_PROVIDER como estado de cuenta en el grupo de usuarios.
Por lo tanto, pensé que podría tratarse de una asignación incorrecta. Fui a la asignación de atributos en la sección Federación y vi que el ID de Facebook y Google Sub se estaban asignando al nombre de usuario, traté de eliminarlo y por mi sorpresa, fue asignado de nuevo al nombre de usuario. Luego pensé: "Puedo crear un atributo personalizado para almacenar esa información y debería estar bien".
Así que hice esto, creé un atributo para Facebook, uno para GoogleId... lo intenté de nuevo... no, sigo volviendo al nombre de usuario, pero no hay mensaje de error, nada...
Fui por ayuda en la documentación y encontré esto
Actualmente, solo los atributos de ID de Facebook, sub de Google, inicio de sesión con ID de usuario de Amazon e inicio de sesión con sub de Apple se pueden asignar al atributo de nombre de usuario de grupos de usuarios de Amazon Cognito.
Si esto siempre asocia cada ID de proveedor con el nombre de usuario, entonces, no hay forma de fusionar esas cuentas. Pensé que podría ser que necesitaba configurar un grupo de identidades federadas, pero al leerlo, parece que se usa para otorgar roles de IAM/ permiso a los usuarios externos, que no quiero.
¿Alguna idea de cómo puedo lograr eso?
Después de investigar un poco, encontré la solución. En resumen, usted debe:
Puede crear el disparador desde Amplify cli, ejecutar la amplify auth update , hacer el "Recorrido por todas las configuraciones de autenticación", al final, le preguntará si desea crear el disparador, confírmelo y seleccione el disparador de registro previo
Luego edite el archivo de función creado, el tiempo de ejecución predeterminado es nodejs , he cambiado el mío a Python
Este es el código que estoy usando
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