AWS Amplify:如何为基于电子邮件的身份验证映射社交提供程序属性? [英] AWS Amplify: How to map social providers attributes for an email based authentication?

查看:174
本文介绍了AWS Amplify:如何为基于电子邮件的身份验证映射社交提供程序属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用AWS Amplify构建的React Web应用程序 我已经使用Cognito用户池添加了身份验证,我没有使用用户名,只选择了使用电子邮件/电话登录,我不希望使用用户名,但是Cognito仍然会创建一个随机的用户名.

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.

我希望用户使用电子邮件或使用一个社交服务提供商(Facebook或Google)登录,这没关系,他们应该可以基于电子邮件访问同一帐户.

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.

我认为这是很正常的做法. 但是,当我第一次尝试使用社交服务提供商登录时,我发现不是Cognito给我提供了相同的帐户,而是创建了一个新帐户,并使用了不同的用户名,并以EXTERNAL_PROVIDER作为用户池上的帐户状态

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

所以,我认为可能只是一些映射不正确,我去了联合身份验证"部分的属性"映射,然后看到Facebook ID和Google Sub被分配了用户名,我试图将其删除令我惊讶的是,它被分配回了用户名. 然后我想:我可以创建一个自定义属性来存储该信息,应该没问题."

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".

所以我这样做了,为Facebook创建了一个属性,为GoogleId创建了一个属性...再次尝试...不,仍然返回到用户名,但是没有错误消息,没什么...

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

当前,只有Facebook id,Google子目录,使用Amazon user_id登录和使用Apple子登录属性可以映射到Amazon Cognito用户池用户名属性.

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.

如果这始终将每个提供商ID与用户名相关联,则无法合并这些帐户 我以为可能需要设置一个联合身份池,但是阅读它似乎是用来向外部用户提供IAM角色/权限,这是我不希望的.

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?

推荐答案

深入研究它之后,我找到了解决方案. 总之,您应该:

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

  • 在Cognito上为lambda函数的预注册创建触发器
  • 此lambda函数应找到相应的帐户并链接两个用户
  • 从lambda函数返回事件

您可以从Amplify cli创建触发器,运行amplify auth update,执行遍历所有身份验证配置",最后,将询问您是否要创建触发器,确认并选择预注册触发器

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

然后编辑创建的功能文件,默认运行时间为nodejs,我将我的更改为Python

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

这是我正在使用的代码

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

这篇关于AWS Amplify:如何为基于电子邮件的身份验证映射社交提供程序属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆