为我的应用创建了一个配置文件页面后,我想显示该用户所在的社交服务列表。它让我感到最简单的方法就是使用Meteor的内置账户系统。如何将外部服务登录添加到Meteor中已有的帐户?
有没有一种很好的方式将外部服务添加到现有帐户?
此外,用户是否可以使用他的密码从我的应用程序(例如)Facebook 和登录?
另一个自然会出现的问题:是否有一种很好的方法可以将特定于应用程序的密码添加到使用外部服务创建的帐户中?
为我的应用创建了一个配置文件页面后,我想显示该用户所在的社交服务列表。它让我感到最简单的方法就是使用Meteor的内置账户系统。如何将外部服务登录添加到Meteor中已有的帐户?
有没有一种很好的方式将外部服务添加到现有帐户?
此外,用户是否可以使用他的密码从我的应用程序(例如)Facebook 和登录?
另一个自然会出现的问题:是否有一种很好的方法可以将特定于应用程序的密码添加到使用外部服务创建的帐户中?
是的,一个用户帐户可以与多个服务相关联,并且同时具有基于密码的登录。在Meteor docs,你可以看到这样的用户帐户的结构:
{
_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: "[email protected]", verified: true },
{ address: "[email protected]", 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 }
]
}
}
}
如果在添加用户名/密码登录到现有的帐户,您可以在服务器端使用Accounts.sendResetPasswordEmail
。这也确保更改发生认证和授权。
当然,您也可以自己更新服务器端的用户记录并使用新密码,但这可能会在您的应用程序中创建一个安全漏洞。如果可能的话,我也建议不要实施你自己的加密协议,如it is hard。
如果你想比电子邮件添加其他服务,例如,您可以
Accounts.loginWith[OtherService]
将用户重新登录到其他服务。这将使用户在另一服务上使用新帐户登录并重新登录。这是我如何添加凭据现有用户帐户:.../meteor-how-to-login-with-github-account.html
尽管这可能在理论上回答这个问题,但[这将是更可取的](http://meta.stackoverflow.com/q/8259)在这里包含了答案的基本部分,并提供了供参考的链接。 – 2015-08-08 09:41:03
这里是一个替代方法。在这个解决方案中,我重写了一个核心函数并添加了一些自定义行为。我的目标是将服务数据与当前登录的用户相关联,然后让核心功能像正常一样完成它的工作。
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);
}
优点:
缺点:
这看起来像我可以找到的最佳答案,但我无法使其工作。我将它添加到服务器上运行,包括accounts-password和accounts-facebook。然后我用密码登录,调用Meteor.loginWithFacebook(),并向Meteor().user()添加一个空的服务对象。它还在服务器控制台中记录一个错误,该错误说:调用方法'login'时发生异常错误:只能在方法调用中调用Meteor.userId。在发布函数中使用this.userId。 – fnsjdnfksjdb 2014-02-03 05:46:06
查看本示例中的示例并回答。它几乎为您提供了集成多个外部和内部帐户的代码。只需稍作调整,您可以根据需要为每个帐户添加密码字段。
How to use Meteor.loginWithGoogle with mrt:accounts-ui-bootstrap-dropdown
代码:
isProdEnv = function() {
if (process.env.ROOT_URL == "http://localhost:3000") {
return false;
} else {
return true;
}
}
Accounts.loginServiceConfiguration.remove({
service: 'google'
});
Accounts.loginServiceConfiguration.remove({
service: 'facebook'
});
Accounts.loginServiceConfiguration.remove({
service: 'twitter'
});
Accounts.loginServiceConfiguration.remove({
service: 'github'
});
if (isProdEnv()) {
Accounts.loginServiceConfiguration.insert({
service: 'github',
clientId: '00000',
secret: '00000'
});
Accounts.loginServiceConfiguration.insert({
service: 'twitter',
consumerKey: '00000',
secret: '00000'
});
Accounts.loginServiceConfiguration.insert({
service: 'google',
appId: '00000',
secret: '00000'
});
Accounts.loginServiceConfiguration.insert({
service: 'facebook',
appId: '00000',
secret: '00000'
});
} else {
// dev environment
Accounts.loginServiceConfiguration.insert({
service: 'github',
clientId: '11111',
secret: '11111'
});
Accounts.loginServiceConfiguration.insert({
service: 'twitter',
consumerKey: '11111',
secret: '11111'
});
Accounts.loginServiceConfiguration.insert({
service: 'google',
clientId: '11111',
secret: '11111'
});
Accounts.loginServiceConfiguration.insert({
service: 'facebook',
appId: '11111',
secret: '11111'
});
}
Accounts.onCreateUser(function (options, user) {
if (user.services) {
if (options.profile) {
user.profile = options.profile
}
var service = _.keys(user.services)[0];
var email = user.services[service].email;
if (!email) {
if (user.emails) {
email = user.emails.address;
}
}
if (!email) {
email = options.email;
}
if (!email) {
// if email is not set, there is no way to link it with other accounts
return user;
}
// see if any existing user has this email address, otherwise create new
var existingUser = Meteor.users.findOne({'emails.address': email});
if (!existingUser) {
// check for email also in other services
var existingGitHubUser = Meteor.users.findOne({'services.github.email': email});
var existingGoogleUser = Meteor.users.findOne({'services.google.email': email});
var existingTwitterUser = Meteor.users.findOne({'services.twitter.email': email});
var existingFacebookUser = Meteor.users.findOne({'services.facebook.email': email});
var doesntExist = !existingGitHubUser && !existingGoogleUser && !existingTwitterUser && !existingFacebookUser;
if (doesntExist) {
// return the user as it came, because there he doesn't exist in the DB yet
return user;
} else {
existingUser = existingGitHubUser || existingGoogleUser || existingTwitterUser || existingFacebookUser;
if (existingUser) {
if (user.emails) {
// user is signing in by email, we need to set it to the existing user
existingUser.emails = user.emails;
}
}
}
}
// precaution, these will exist from accounts-password if used
if (!existingUser.services) {
existingUser.services = { resume: { loginTokens: [] }};
}
// copy accross new service info
existingUser.services[service] = user.services[service];
existingUser.services.resume.loginTokens.push(
user.services.resume.loginTokens[0]
);
// even worse hackery
Meteor.users.remove({_id: existingUser._id}); // remove existing record
return existingUser; // record is re-inserted
}
});
我在学习,你能做到它喜欢它的答案,或者您自己的方式解释真实? – jptsetung 2013-05-19 13:53:55
[使用流星帐户包链接多个服务]可能的重复(http://stackoverflow.com/questions/18358007/using-meteor-accounts-package-to-link-multiple-services) – BenjaminRH 2013-09-02 15:28:52