如何将外部服务登录添加到Meteor中现有的帐户?

Swa*_*adq 8 meteor

为我的应用创建了个人资料页面后,我想显示用户所在的社交服务列表.让我感到震惊的是,最简单的方法是使用Meteor的内置帐户系统.

有没有一种向现有帐户添加外部服务的好方法?

此外,用户是否能够使用(例如)Facebook 他的密码从我的应用程序登录?

自然遵循的另一个问题是:有没有一种方法可以将特定于应用程序的密码添加到使用外部服务创建的帐户?

jru*_*ann 7

这是另一种方法.在这个解决方案中,我重写了核心功能并添加了一些自定义行为.我的目标是将服务数据与当前登录的用户相关联,然后允许核心功能像正常一样执行其操作.

orig_updateOrCreateUserFromExternalService = Accounts.updateOrCreateUserFromExternalService;
Accounts.updateOrCreateUserFromExternalService = function(serviceName, serviceData, options) {
  var loggedInUser = Meteor.user();
  if(loggedInUser && typeof(loggedInUser.services[serviceName]) === "undefined") {
    var setAttr = {};
    setAttr["services." + serviceName] = serviceData;
    Meteor.users.update(loggedInUser._id, {$set: setAttr});
  }
  return orig_updateOrCreateUserFromExternalService.apply(this, arguments);
}
Run Code Online (Sandbox Code Playgroud)

优点:

  • 避免创建不必要的帐户
  • 代码简短易懂
  • 如果将此功能添加到Meteor核心,则很容易删除代码

缺点:

  • 需要用户登录.如果用户最初使用Twitter登录,注销,然后使用Facebook登录,则将创建两个单独的帐户.
  • 共享计算机的用户可能会无意中合并其帐户.
  • 依赖于updateOrCreateUserFromExternalService如何工作的知识.这并不可怕 - 因为它是Meteor的公共API的一部分,它可能不会彻底改变(不管怎么说).但它仍然存在风险.


opy*_*pyh 1

是的,一个用户帐户可以与多个服务关联,并同时具有基于密码的登录。在Meteor 文档中,您可以看到这样一个用户帐户的结构:

{
  _id: "bbca5d6a-2156-41c4-89da-0329e8c99a4f",  // Meteor.userId()
  username: "cool_kid_13", // unique name
  emails: [
    // each email address can only belong to one user.
    { address: "cool@example.com", verified: true },
    { address: "another@different.com", verified: false }
  ],
  createdAt: 1349761684042,
  profile: {
    // The profile is writable by the user by default.
    name: "Joe Schmoe"
  },
  services: {
    facebook: {
      id: "709050", // facebook id
      accessToken: "AAACCgdX7G2...AbV9AZDZD"
    },
    resume: {
      loginTokens: [
        { token: "97e8c205-c7e4-47c9-9bea-8e2ccc0694cd",
          when: 1349761684048 }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

要向现有帐户添加用户名/密码登录,您可以Accounts.sendResetPasswordEmail在服务器端使用。这也确保了更改是经过身份验证和授权的。

当然,您也可以自己使用新密码更新服务器端的用户记录,但这可能会在您的应用程序中造成安全漏洞。如果可能的话,我还建议不要为此实施自己的加密协议,因为这很困难

如果您想添加电子邮件以外的其他服务,您可以例如

  1. 调用一个服务器方法,该方法在当前用户的 MongoDB 文档中保存一个随机的长令牌并将其返回给客户端。
  2. 使用另一个服务重新登录用户Accounts.loginWith[OtherService]。这将用户注销并使用其他服务上的新帐户再次登录。
  3. 使用第一个方法返回的令牌作为参数调用第二个服务器方法。第二种方法搜索具有给定令牌的用户帐户并将其数据合并到当前(新)帐户中。