Проблема с учетными записями пользователей Meteor - дублирующаяся учетная запись создается с помощью службы OAuth (accounts-google) - PullRequest
1 голос
/ 30 мая 2020

Я работаю с учетными записями пользователей Meteor для создания пользователей. Я реализовал два способа создания пользователей.

  1. Используя account-password для создания (по умолчанию).
  2. OAuth Services ( accounts-google и accounts-facebook )

Учетная запись пользователя, созданная с помощью accounts-password иметь документ, показанный ниже

{
  "_id": "DQnDpEag2kPevSdJY",
  "createdAt": "2015-12-10T22:34:17.610Z",
  "services": {
    "password": {
      "bcrypt": "XXX"
    },
    "resume": {
      "loginTokens": [
        {
          "when": "2015-12-10T22:34:17.615Z",
          "hashedToken": "XXX"
        }
      ]
    }
  },
 -----
----
}

Где в качестве учетной записи пользователя, созданной с помощью accounts-google или account-facebook , иметь документ, показанный ниже.

{
  "_id": "Ap85ac4r6Xe3paeAh",
  "createdAt": "2015-12-10T22:29:46.854Z",
  "services": {
    "facebook": {
      "accessToken": "XXX",
      "expiresAt": 1454970581716,
      "id": "XXX",
      "email": "myname@gmail.com",
      "name": "Ada Lovelace",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "link": "https://www.facebook.com/app_scoped_user_id/XXX/",
      "gender": "female",
      "locale": "en_US",
      "age_range": {
        "min": 21
      }
    },
---
---
---

Теперь реальная проблема заключается в том, что, хотя используемый адрес электронной почты одинаков как для учетных записей-паролей, так и для учетных записей-google (в моем случае адрес электронной почты myname@gmail.com), создаются две разные учетные записи пользователей.

Ищу решение Примерно ниже. (Примечание: Сервисы имеют разделы «Пароль» и «Facebook» под одной учетной записью)

{
  "_id": "DQnDpEag2kPevSdJY",
  "createdAt": "2015-12-10T22:34:17.610Z",
  "services": {
    "password": {
      "bcrypt": "XXX"
    },
    "facebook": {
      "accessToken": "XXX",
      "expiresAt": 1454970581716,
      "id": "XXX",
      "email": "myname@gmail.com",
      "name": "Ada Lovelace",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "link": "https://www.facebook.com/app_scoped_user_id/XXX/",
      "gender": "female",
      "locale": "en_US",
      "age_range": {
        "min": 21
      }
    },
  },
 -----
----
}

Есть ли способ, при котором только одна учетная запись создается в обоих случаях, означает, что пользователь уже существует и то же самое происходит со службой OAuth, первая учетная запись должна использоваться для размещения службы?

Ответы [ 3 ]

2 голосов
/ 22 июня 2020
Пакет

link-accounts - это рекомендуемый способ, позволяющий пользователям добавлять дополнительные услуги в свою учетную запись.

1 голос
/ 02 июня 2020

Я решил эту проблему с помощью хака.

В imports/startup/server/accounts.js Я добавил ниже журнал проверки c, который всегда проверяет вновь созданную учетную запись.

Идея в том, что этот процесс проверяет, является ли пользователь уже существует в базе данных. Если пользователь существует, дополнительно проверяет, создан ли он из accounts-password или accounts-google/facebook.

На основе существующего типа измените существующие поля новыми полями и выдайте ошибку с причудливым сообщением (это фактически предотвращает будет создана новая учетная запись).

Accounts.validateNewUser(function (user) {

// first check what is the newly creating service
  var service =
    user.services.google || user.services.facebook || user.services.password;


  if (!service) return true;

  var existingUser = null;
// due to some issues both `Meteor.users.findOne(email)` as well `Account.findUserByEmail(email)` methods have been used to find the existing user status

  if (user.services.password) {
    var email = user.emails[0].address;
    existingUser = Meteor.users.findOne({
      $or: [
        { "registered_emails[0].address": email },
        { "services.google.email": email },
        { "services.facebook.email": email },
      ],
    });

  } else {
    var email = service.email;
    //console.log(" retrieved email ", email);
    existingUser = Accounts.findUserByEmail(email);
  }

  //console.log(" existingUser  : ", existingUser);
  if (!existingUser) return true;

  if (user.services.google) {
    Meteor.users.update(
      { _id: existingUser._id },
      {
        $set: {
          profile: user.profile,
          "services.google": user.services.google,
        },

      }
    );
  } else if (user.services.facebook) {
    Meteor.users.update(
      { _id: existingUser._id },
      {
        $set: {
          profile: user.profile,
          "services.facebook": user.services.facebook,
        },

      }
    );
  } else {
    Meteor.users.update(
      { _id: existingUser._id },
      {
        $set: {
          profile: user.profile,
          "services.password": user.services.password,
          "services.email": user.services.email,
          emails: user.emails,
        },

      }
    );
  }

  throw new Meteor.Error(
    205,
    "Merged with your existing Social Login accounts now. Try refresh the page and sign in again. That should work !!"
  );
});
1 голос
/ 30 мая 2020

Вы можете использовать Accounts.setPassword на сервере для создания правильного bcrypt ha sh для учетных записей:

Accounts.setPassword('Ap85ac4r6Xe3paeAh', 'the-new-password')

, который будет Результат будет

{
  "_id": "Ap85ac4r6Xe3paeAh",
  "createdAt": "2015-12-10T22:29:46.854Z",
  "services": {
    "password": {
      "bcrypt": "$2b$10$nzHCivxVqxbuFBBPWewPPu.r5x7OR5gJB8PIklU4OoU.WK0MT8jt2"
    },
    "facebook": {
      "accessToken": "XXX",
      "expiresAt": 1454970581716,
      "id": "XXX",
      "email": "myname@gmail.com",
      "name": "Ada Lovelace",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "link": "https://www.facebook.com/app_scoped_user_id/XXX/",
      "gender": "female",
      "locale": "en_US",
      "age_range": {
        "min": 21
      }
    }
  }
}
...