Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oauth 使用Meteor帐户包链接多个服务_Oauth_Meteor - Fatal编程技术网

Oauth 使用Meteor帐户包链接多个服务

Oauth 使用Meteor帐户包链接多个服务,oauth,meteor,Oauth,Meteor,所以Meteor有这个很棒的帐户包,可以通过密码或其他服务轻松登录。然而,我目前正在创建一个需要多种服务的web服务(facebook/twitter/etc)。这里的链接:建议通过创建重复帐户和合并数据进行“黑客攻击”,但这对我来说似乎非常不满意 因此,我的问题是: 1) 是否有一种更优雅的方式来使用Accounts xxx包创建一个用户,但附加了多个服务? 2) 如果没有,我可以使用现在分离的oauth包将令牌添加到一个用户上。例如,如果github令牌是在以后手动“附加”的,Account

所以Meteor有这个很棒的帐户包,可以通过密码或其他服务轻松登录。然而,我目前正在创建一个需要多种服务的web服务(facebook/twitter/etc)。这里的链接:建议通过创建重复帐户和合并数据进行“黑客攻击”,但这对我来说似乎非常不满意

因此,我的问题是:

1) 是否有一种更优雅的方式来使用Accounts xxx包创建一个用户,但附加了多个服务? 2) 如果没有,我可以使用现在分离的oauth包将令牌添加到一个用户上。例如,如果github令牌是在以后手动“附加”的,Accounts.loginWithGithub还会在以后找到手动合并的帐户吗? 谢谢你的帮助。

解决了! 我已经通过逆向工程
accounts-oauth-X
包解决了这个问题!处理所有边缘情况的最佳解决方案是,一个故事用于登录,另一个故事用于显式关联。以下是用有文化的咖啡脚本编写的解决方案

之前: 确保您拥有所需的软件包:

meteor add google
meteor add facebook
meteor add oauth
具有多服务登录的方法: 如果帐户具有相同的电子邮件,则会自动加入帐户。最好用于登录,因为它很健壮。但是,这不利于显式关联,因为如果电子邮件地址不同,那么它将不起作用。(手动合并将注销用户并强制您重新登录)。要明确关联帐户,即使它有不同的电子邮件,请参阅下面的解决方案

服务器端代码: 如果用户通过oauth服务注册,我们需要执行额外的逻辑,以便 我们可以标准化姓名和电子邮件的位置

  if user.services?
    service = _.keys(user.services)[0]
检查是否有任何现有帐户已将电子邮件与 服务如果是这样,只需将用户信息合并到

    email = user.services[service].email
    if email?
      oldUser = Meteor.users.findOne({"emails.address": email})
确保旧帐户具有所需的服务对象

      if oldUser?
        oldUser.services ?= {}
        if service == "google" or service == "facebook"
将新服务密钥合并到旧用户中。我们也会检查是否有新的 电子邮件添加到我们的用户。然后从数据库中删除旧用户,然后 再次返回以直接重新创建。要访问的假定新用户 被创建的对象将被丢弃

          oldUser.services[service] = user.services[service]
          Meteor.users.remove(oldUser._id)
          user = oldUser
否则,只需正常创建用户,标准化电子邮件和姓名字段

      else
        if service == "google" or service == "facebook"
          if user.services[service].email?
            user.emails = [{address: user.services[service].email, verified: true}]
          else
            throw new Meteor.Error(500, "#{service} account has no email attached")
          user.profile.name = user.services[service].name

  return user
显式关联的方法: 这会将服务添加到用户记录上的服务散列中,就像它是由内置散列系统创建的一样。代码需要是客户端(获取服务oauth令牌)和部分服务器端(进行进一步的API调用以获取用户数据并将其与用户记录关联)

客户端代码: 此函数是向我们的帐户添加函数的入口点

addUserService = (service) ->
      when "facebook"
        Facebook.requestCredential(
          requestPermissions: ["email", "user_friends", "manage_notifications"],
        , (token) ->
          Meteor.call "userAddOauthCredentials", token, Meteor.userId(), service, (err, resp) ->
            if err?
              Meteor.userError.throwError(err.reason)
        )
      when "google"
        Google.requestCredential
          requestPermissions: ["email", "https://www.googleapis.com/auth/calendar"]
          requestOfflineToken: true,
        , (token) ->
          Meteor.call "userAddOauthCredentials", token, Meteor.userId(), service, (err, resp) ->
            if err?
              Meteor.userError.throwError(err.reason)
如果他们选择电子邮件,我们需要使用Meteor的内置电子邮件验证系统

  if service == "email"

  else
    switch service
对于标准oauth服务,我们在客户端请求凭据,并且 然后将它们传递给服务器,以执行进一步的API调用来收集数据 必要的信息,并将该信息添加到我们的账户中

addUserService = (service) ->
      when "facebook"
        Facebook.requestCredential(
          requestPermissions: ["email", "user_friends", "manage_notifications"],
        , (token) ->
          Meteor.call "userAddOauthCredentials", token, Meteor.userId(), service, (err, resp) ->
            if err?
              Meteor.userError.throwError(err.reason)
        )
      when "google"
        Google.requestCredential
          requestPermissions: ["email", "https://www.googleapis.com/auth/calendar"]
          requestOfflineToken: true,
        , (token) ->
          Meteor.call "userAddOauthCredentials", token, Meteor.userId(), service, (err, resp) ->
            if err?
              Meteor.userError.throwError(err.reason)
我们只需要设置一个简单的绑定将其粘合在一起

Template.userAddServices.events
  "click button": (e) ->
    e.preventDefault()
    service = $(event.target).data("service")
    addUserService(service)
服务器端代码: 这里我们定义与用户模型相关的服务器端方法

Meteor.methods
这将从客户端传递数据,客户端获取访问令牌 已经。使用令牌来发现有关用户的其余信息 在那项服务上。然后检查该帐户是否已注册, 如果没有,则将其添加到活期账户中

  userAddOauthCredentials: (token, userId, service) ->
    switch service
      when "facebook"
        data = Facebook.retrieveCredential(token).serviceData
      when "google"
        data = Google.retrieveCredential(token).serviceData

    selector = "services.#{service}.id"
    oldUser = Meteor.users.findOne({selector: data.id})
    if oldUser?
      throw new Meteor.Error(500, "This #{service} account has already" +
      "been assigned to another user.")

    updateSelector = "services.#{service}"
    Meteor.users.update(userId, {$set: {updateSelector: data }})
我们还可以从这个帐户中查看电子邮件。如果它还没有在 当前用户,我们可以抓取并添加它

    if not _.contains(Meteor.user().emails, data.email)
      Meteor.users.update(userId, {$push: {"emails": {address: data.email, verified: true} }})

删除现有用户可能会在某些senarios中产生问题。在我的用例中,我需要在使用另一个oauth帐户登录系统时合并google帐户。这可以通过以下修改来实现

修改Accounts.onCreateUser Accounts.onCreateUser(函数(选项,用户){

}))

修改帐户基本包 包/Accounts base/Accounts\u server.js的Accounts.insertUserDoc函数中的行应替换为以下代码。希望流星能解决这个问题。在此之前,必须使用自定义包

if(Meteor.users.findOne(fullUser._id)){
  userId = fullUser._id;
  delete fullUser._id;
  Meteor.users.update(userId, {$set: fullUser});
} else
  userId = Meteor.users.insert(fullUser);

啊!!为什么我要等两天才能拿到赏金?我很想在这里看到一个好的答案。这不是创造了一个潜在的途径来控制某人的帐户吗?假设John只在facebook登录时创建了一个帐户。如果我知道约翰的电子邮件地址,难道我不能注册它,然后它会让我登录,并通过facebook登录将我连接到他的帐户吗?很好。我想这将需要我们为更安全的交易提供更多的便利——在这种情况下,只使用下半部分的“显式关联”。你需要要求电子邮件验证以防止劫持问题。这个答案包含了这么多赢,我想把你提升到第十五,第十四!
if(Meteor.users.findOne(fullUser._id)){
  userId = fullUser._id;
  delete fullUser._id;
  Meteor.users.update(userId, {$set: fullUser});
} else
  userId = Meteor.users.insert(fullUser);