首页 文章

将服务连接到现有的meteor帐户

提问于
浏览
11

我正在设置一个流星应用程序,涉及注册用户名和密码,然后希望将该帐户与Facebook和Twitter连接 .

我的第一部分很容易上手,只需使用帐户包 . 但是当我有一个登录用户调用Meteor.loginWithFacebook()时,它会将它们记录下来并创建一个新帐户 . 我想要的是将facebook凭据添加到当前登录用户的内容 .

流星文档有这个:

{
  _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: Wed Aug 21 2013 15:16:52 GMT-0700 (PDT),
  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 }
      ]
    }
  }
}

这似乎是一个帐户,其用户名也通过Facebook验证 . 但我不确定这是否只是一个你无法用基本的Meteor实际实现的例子 .

我想要做的基本上是

Meteor.connectWithExternalAccount();

它运行与Meteor.loginWithExternalAccount()相同的进程,但只是将信息添加到当前登录的用户 .

如果有人可以稍微解释基于帐户的程序包,那么我就可以知道从哪里开始,这将是非常好的 .

此外,有没有人知道这是否将包含在任何未来的Meteor版本中?

2 回答

  • 6

    所以有一些工作要解决这个问题,但遗憾的是拉动请求https://github.com/meteor/meteor/pull/1133从未合并过 . 可能你最好的选择是检查流星核心的Google网上论坛,看看是否有任何评论,如果没有,看看你是否可以得到一个核心开发者来评论它 .

    如果你仍想使用拉取请求,你可以做的是删除各种Meteor accounts-* 包,然后在项目的根目录中创建一个 /packages 文件夹,并在那里复制yubozhao的补丁 accounts-* 包(可能很聪明地附加 -custom ) . 然后你将 meteor add accounts-base-custom 等添加到你的项目中 .

    但是请注意,yubozhao在6-7个月之前写道,你可能需要坚持使用当时流行的任何版本的Meteor .

    2014年4月更新:现在有一个Atmosphere包,它有一个类似的用例,可能很有用:https://atmospherejs.com/package/accounts-merge

  • 3

    这是一个适合我的代码(在服务器文件夹内):

    Accounts.onCreateUser(function(options, user) {
        var email, oldUser, service;
        /*
        user.groups = {
            created: "",
            invited:"",
            RSVP:{
                coming:"",
                notComing:"",
                noReplay:""
            }
        };
        */
        if (user.profile == null) {
            user.profile = options.profile
        }
        if (user.services != null) {
            service = _.keys(user.services)[0];
            email = user.services[service].email;
            if (email != null) {
                oldUser = Meteor.users.findOne({
                    "emails.address": email
                });
                if (oldUser != null) {
                    if (oldUser.services == null) {
                        oldUser.services = {};
                    }
                    if (service === "google" || service === "facebook") {
                        oldUser.services[service] = user.services[service];
                        Meteor.users.remove(oldUser._id);
                        user = oldUser;
                    }
                } else {
                    if (service === "google" || service === "facebook") {
                        if (user.services[service].email != null) {
                            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;
    });
    
    userAddOauthCredentials: function(token, userId, service) {
            var data, oldUser, selector, updateSelector;
            switch (service) {
                case "facebook":
                    data = Facebook.retrieveCredential(token).serviceData;
                    break;
                case "google":
                    data = Google.retrieveCredential(token).serviceData;
            }
            selector = "services." + service + ".id";
            oldUser = Meteor.users.findOne({
                selector: data.id
            });
            if (oldUser != null) {
                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 (!_.contains(Meteor.user().emails, data.email)) {
                return Meteor.users.update(userId, {
                    $push: {
                        "emails": {
                            address: data.email,
                            verified: true
                        }
                    }
                });
            }
        }
    

    在客户端js文件夹中:

    var addUserService;
    
    addUserService = function(service) {
        if (service === "email") {
    } else {
        switch (service) {
            case "facebook":
                return Facebook.requestCredential({
                    requestPermissions: ["email", "user_friends", "manage_notifications"]
                }, function(token) {
                    return Meteor.call("userAddOauthCredentials", token, Meteor.userId(), service, function(err, resp) {
                        if (err != null) {
                            return Meteor.userError.throwError(err.reason);
                        }
                    });
                });
            case "google":
                return Google.requestCredential({
                    requestPermissions: ["email", "https://www.googleapis.com/auth/calendar"],
                    requestOfflineToken: true
                }, function(token) {
                    return Meteor.call("userAddOauthCredentials", token, Meteor.userId(), service, function(err, resp) {
                        if (err != null) {
                            return Meteor.userError.throwError(err.reason);
                        }
                    });
                });
        }
    }
    

    };

    模板事件中的相同js文件:

    "click a": function(e) {
           var service;
            e.preventDefault();
            service = $(event.target).data("service");
            return addUserService(service);
        }
    

    而对于html刚做完这个:

    <div class="social"><a id="fb" data-service="facebook"><img src="/../facebook.png"></a></div>
        <div class="social"><a id="go" data-service="google"><img src="/../googleplus.png"></a></div>
    

    主要是您需要将数据服务设置为您的服务,然后模板单击事件获取数据服务并执行addUserService(数据传递) .

    希望它能奏效,请告诉我 .

相关问题