如何在不知道用户的Google SUB的情况下将Google用户与AWS Cognito的用户池关联

时间:2019-08-15 08:00:33

标签: aws-lambda google-oauth amazon-cognito

我想将用户设置到我的用户池中,并允许他们使用用户名+密码或Google的SSO,只要电子邮件匹配即可。使用adminLinkProviderForUser进行链接时,我需要事先提供用户不知道的Google SUB。

1 个答案:

答案 0 :(得分:0)

这是我的解决方案,希望对您有所帮助。如果有人有更好的解决方案,请让我知道:

在我的注册前Lambda中,我提取了Google的SUB和电子邮件,寻找用户并将它们与AdminLinkProviderForUser链接,完成类似的操作后,我在错误中返回了MARGED_GOOGLE字符串。错误字符串将在回调URL中发送到浏览器,我在其中标识了MARGED_GOOGLE字符串,并告诉用户我们刚刚完成了帐户注册,因此他需要重新登录。下次他登录时,链接存在,并且没有注册。

const AWS = require("aws-sdk");
exports.handler = (event, context, callback) => {
  if (event.triggerSource === "PreSignUp_ExternalProvider") {
    if (event.userName.startsWith("Google_")) {
      AWS.config.update({ region: "us-east-2" });
      const COGNITO_CLIENT = new AWS.CognitoIdentityServiceProvider({
        apiVersion: "2016-04-18",
        region: "us-east-2"
      });

      const  adminGetUserParams = {
        UserPoolId: "<UserPoolId>" /* required */,
        Username: event.request.userAttributes.email /* required */
      };
      COGNITO_CLIENT.adminGetUser(adminGetUserParams, function(err, data) {
        if (err) {
          callback("no signed in", null);
        } else {
          // successful response
          const params = {
            DestinationUser: {
              /* required */
              ProviderAttributeValue: data.Username,
              ProviderName: "Cognito"
            },
            SourceUser: {
              /* required */
              ProviderAttributeName: "Cognito_Subject",
              ProviderAttributeValue: event.userName.substr(7),
              ProviderName: "Google"
            },
            UserPoolId: "<UserPoolId>" /* required */
          };
          COGNITO_CLIENT.adminLinkProviderForUser(params, (e, d) => {
            if (e) callback("no signed in", null);
            else {
              callback("MARGED_GOOGLE", null);
            }
          });
        }
      });
    } else {
      callback("no signed in", null);
    }
  } else {
    callback(null, event);
  }
};