Meteor - 验证'onCreateUser'中的多OAuth帐户

时间:2015-09-29 02:30:33

标签: validation meteor meteor-accounts

我正在尝试使用多OAuth(facebook,google)登录服务登录单个用户。这是我尝试的。 在客户端:

'click #signInByFacebook': function (e) {
    e.preventDefault();
    Meteor.loginWithFacebook({requestPermissions: ['public_profile', 'email', 'user_about_me', 'user_photos']}, function (err, res) {
        if (err) {
            showError($('.alert'), err, 'login');
            return;
        }
        showSuccess($('.alert'), 'login');
        Session.set('notAdmin', !Roles.userIsInRole(Meteor.user(), ["admin"]));
        Router.go('/');
    });
},
'click #signInByGoogle': function (e) {
    e.preventDefault();
    Meteor.loginWithGoogle({requestPermissions: ['profile', 'email', 'openid']}, function (err, res) {
        if (err) {
            showError($('.alert'), err, 'login');
            return;
        }
        showSuccess($('.alert'), 'login');
        Session.set('notAdmin', !Roles.userIsInRole(Meteor.user(), ["admin"]));
        Router.go('/');
    });
}

在服务器中:

Accounts.onCreateUser(function (options, user) {
    if (options.profile) {
        user.profile = options.profile;
    }
    var sameuser = Meteor.users.findOne({$or: [{'emails.address': getEmail(user)}, {'services.facebook.email': getEmail(user)}, {'services.google.email': getEmail(user)}]});
    console.log(sameuser);
    if (sameuser) {
        if (user.services.facebook) {
            console.log("facebook");
             Meteor.users.update({_id: sameuser._id}, {$set: {'services.facebook': user.services.facebook}});
        }
        if (user.services.google) {
            console.log("google");
            Meteor.users.update({_id: sameuser._id}, {$set: {'services.google': user.services.google}});
        }
        return;
    }
    console.log('register success');
    return user;
});
  

此代码将检查登录facebook / google的用户是否拥有   同一封电子邮件或不与当前登录。如果它们是相同的,只是   将信息更新到旧帐户。如果没有,请创建新用户。

这很好用,但是'返回'有问题。在服务器代码中。我不知道应该返回什么以停止创建用户并自动登录到具有相同电子邮件的用户。有人可以帮忙解决这个问题吗?谢谢。

1 个答案:

答案 0 :(得分:1)

停止创建新用户的唯一方法是抛出异常,但这也会阻止以现有用户身份登录。

然而,您的一般方法是不安全的。考虑使用具有强密码的Google帐户和具有弱密码的Facebook帐户的用户。当他使用Google帐户对您的应用进行身份验证时,他不会(也不应该)期望获得访问其Facebook帐户的人能够像他一样访问您的应用。

更好的方法是要求用户在合并服务之前同时登录这两项服务。好消息是,这也意味着您不必担心在阻止创建新用户后登录,因为用户已经登录。这样的事情可能有用:

Accounts.onCreateUser(function (options, user) {
    if (options.profile) {
        user.profile = options.profile;
    }
    var currentUser = Meteor.user();
    console.log(currentUser);
    if (currentUser) {
        if (user.services.facebook) {
            console.log("facebook");
             Meteor.users.update({_id: currentUser._id}, {$set: {'services.facebook': user.services.facebook}});
        }
        if (user.services.google) {
            console.log("google");
            Meteor.users.update({_id: currentUser._id}, {$set: {'services.google': user.services.google}});
        }
        throw new Meteor.Error(Accounts.LoginCancelledError.numericError, "Service added to existing user (or something similar)");;
    }
    console.log('register success');
    return user;
});

还有一些松散的结局。首先,我认为Meteor希望将OAuth凭据“固定”给与之关联的用户,因此您可能需要重新复制正在复制的凭据。

其次,上述方法绕过了validateLoginAttempt()回调。如果您或您正在使用的任何软件包已经注册了任何此类回调,则在使用第二个服务登录时将不会调用它们,因此他们将无法阻止任何他们认为无效的登录。

您可以解决这两个问题并跳过onCreateUser()回调,只需将我的brettle:accounts-add-service包添加到您的应用中即可。