amazon-web-services - AWS Cognito : Best practice to handle same user (with same email address) signing in from different identity providers (Google, Facebook)

标签 amazon-web-services aws-lambda amazon-cognito google-signin amazon-cognito-facebook

通过 Google 和 Facebook 身份提供商使用相同的电子邮件地址登录用户时,AWS Cognito 在用户池中创建多个条目,每个身份提供商使用一个条目:

Screenshot of AWS Cognito user pool

我已使用本教程中提供的示例代码来设置 AWS Cognito:The Complete Guide to User Authentication with the Amplify Framework

  • 如何只创建一个用户而不是多个用户?
  • 是否可以让 AWS Cognito 自动组合(联合)条目
    从多个提供商到一个条目,还是应该使用 AWS Lambda 函数来完成此操作?
  • 最佳答案

    是的。您可以使用 AdminLinkProviderForUser https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminLinkProviderForUser.html

    这个想法是:

  • 在 PreSignUp lambda Hook 中,如果用户已经注册,我们将提供者链接到用户。例如:

  • import CognitoIdentityServiceProvider from 'aws-sdk/clients/cognitoidentityserviceprovider'
    
    const cognitoIdp = new CognitoIdentityServiceProvider()
    const getUserByEmail = async (userPoolId, email) => {
     const params = {
       UserPoolId: userPoolId,
       Filter: `email = "${email}"`
     }
     return cognitoIdp.listUsers(params).promise()
    }
    
    const linkProviderToUser = async (username, userPoolId, providerName, providerUserId) => {
     const params = {
       DestinationUser: {
         ProviderAttributeValue: username,
         ProviderName: 'Cognito'
       },
       SourceUser: {
         ProviderAttributeName: 'Cognito_Subject',
         ProviderAttributeValue: providerUserId,
         ProviderName: providerName
       },
       UserPoolId: userPoolId
     }
    
     const result = await (new Promise((resolve, reject) => {
       cognitoIdp.adminLinkProviderForUser(params, (err, data) => {
         if (err) {
           reject(err)
           return
         }
         resolve(data)
       })
     }))
    
     return result
    }
    
    exports.handler = async (event, context, callback) => {
     if (event.triggerSource === 'PreSignUp_ExternalProvider') {
       const userRs = await getUserByEmail(event.userPoolId, event.request.userAttributes.email)
       if (userRs && userRs.Users.length > 0) {
         const [ providerName, providerUserId ] = event.userName.split('_') // event userName example: "Facebook_12324325436"
         await linkProviderToUser(userRs.Users[0].Username, event.userPoolId, providerName, providerUserId)
       } else {
         console.log('user not found, skip.')
       }
    
     }
     return callback(null, event)
    }
    
  • 然后当用户使用带有用户池的 Facebook/Google 的 OAuth 时,池将返回此用户链接。

  • 注意:您可能会在用户池 UI 中看到 2 条记录,但是当访问用户记录详细信息时,它们已经合并。

    关于amazon-web-services - AWS Cognito : Best practice to handle same user (with same email address) signing in from different identity providers (Google, Facebook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59635482/

    相关文章:

    python - 读取 DynamoDB 表的所有项目

    node.js - 从 Imagemagick 或 Graphicsmagick 获取图像的亮度信息

    amazon-web-services - 从通过 Cognito 生成的授权 token 识别 AWS Lambda 中的用户

    ios - 为什么 AWSCognitoCredentialsProvider.getIdentityId().continueWith(block :) not run its block?

    grails -/home/ec2-user/grails-2.4.3不是Jenkins主目录上的目录(但可能在某些从目录上存在)

    javascript - 如何以编程方式连接到 AWS websocket API Gateway

    amazon-web-services - 对于单个分区键值,DynamoDB 最大分区大小是否为 10GB?

    node.js - 移动自动化 Nodejs Appium AWS

    java - JsonReaderException ,当从 Android 调用 AWS lambda 函数时

    android - 为 Android 应用程序使用开发人员身份验证 (aws cognito) 的示例