我试图使用'角色'在Atmosphere上提供的包但我无法使用Accounts.onCreateUser(),我可以在github上获得示例。当我注册一个用户时,我想为他们添加一个角色,当我测试角色是否被分配时,它没有提起它。
这是我的代码
/server/users.js
Accounts.onCreateUser(function(options, user){
var role = ['admin'];
Roles.addUsersToRoles(user, role);
return user;
});
/client/page.js
Template.hello.events({
'click input': function () {
var loggedInUser = Meteor.user();
if (Roles.userIsInRole(loggedInUser, ['admin'])) {
console.log("Hi Admin!");
}else{
console.log("Please Log In");
}
}
});
答案 0 :(得分:13)
如果查看Roles
包中使用的代码,您会看到他们使用您传入的user / userId对用户的集合(here)执行查询,从第~~行开始623):
try {
if (Meteor.isClient) {
// On client, iterate over each user to fulfill Meteor's
// 'one update per ID' policy
_.each(users, function (user) {
Meteor.users.update({_id: user}, update)
})
} else {
// On the server we can use MongoDB's $in operator for
// better performance
Meteor.users.update(
{_id: {$in: users}},
update,
{multi: true})
}
}
由于在将用户对象插入集合之前调用onCreateUser
(docs:将返回的文档直接插入到Meteor.users集合中),{{ 1}}在执行查询时无法找到它。
要解决此问题,您必须等到用户插入集合中。如果您查看Roles
包,他们的所有示例都会显示此信息。像here,(第二个例子,添加了评论),以及许多其他:
Roles
希望能够解决你的问题。所以基本上只需插入用户,然后再添加权限。
答案 1 :(得分:9)
要在accounts
包插入用户文档后向其添加内容,请尝试使用此模式。请注意,您必须meteor add random
才能生成userId
,这在此上下文中是安全的。
Accounts.onCreateUser(function (options, user) {
// Semantics for adding things to users after the user document has been inserted
var userId = user._id = Random.id();
var handle = Meteor.users.find({_id: userId}, {fields: {_id: 1}}).observe({
added: function () {
Roles.addUsersToRoles(userId, ['admin']);
handle.stop();
handle = null;
}
});
// In case the document is never inserted
Meteor.setTimeout(function() {
if (handle) {
handle.stop();
}
}, 30000);
return user;
});
答案 2 :(得分:5)
我不明白如何将Roles.addUsersToRoles与创建用户时调用的onCreateUser函数集成。正如您所发现的那样,当您在OnCreateUser中调用它时,它不起作用。但是在用户创建循环中调用addUsersToRoles的示例情况似乎不适用于创建帐户的新用户的正常用例。
相反,我只是这样做:
Accounts.onCreateUser(function(options, user){
var role = ['admin'];
user.roles = role
return user;
});
答案 3 :(得分:5)
接受的答案强制您为meteor通过accounts-ui / password给出的登录逻辑编写样板代码。 其他答案对底层实现做出假设,超时解决方案引入竞争条件。
为什么不这样做:
#test

您有效地添加角色 后触发onCreateUser调用的任何内容,并使用alanning的api添加到角色。 (测试流星1.0,角色1.2.13)
答案 4 :(得分:2)
这里的问题实际上归结为寻找帖子创建用户挂钩(onCreateUser
不是)。
postSignUpHook
。
https://github.com/meteor-useraccounts/core/blob/master/Guide.md#options
我从这个答案中找到了这个:
https://stackoverflow.com/a/34114000/3221576
这是向使用样板UserAccounts包创建的用户添加角色的首选方法(即,如果您没有使用Accounts.createUser
滚动自己的角色)。
更新
最终我最终使用matb33:collection-hooks根据这个评论:
https://github.com/alanning/meteor-roles/issues/35#issuecomment-198979601
只需将该代码粘贴在Meteor.startup中即可按预期工作。
答案 5 :(得分:1)
我不想重写Meteor的帐户包给出的逻辑,自己设置ID,或者使用setTimeout。
相反,我有跟踪器代码观看Meteor.user()
调用,如果登录则返回用户,否则返回null。
因此,实际上,一旦用户登录,此代码将检查他们是否已被分配角色以及他们是否未添加角色。
我确实必须使用Meteor方法,因为我不希望角色与客户端混淆,但你可以改变它。
/* client */
Tracker.autorun(function () {
var user = Meteor.user();
if (user && !Roles.getRolesForUser(user).length) {
Meteor.call('addUserRole', user);
}
});
/* server */
Meteor.methods({
addUserRole: function (user) {
Roles.addUsersToRoles(user, user.profile.edmodo.type);
},
});
答案 6 :(得分:0)
我发现这样做很简单。
我将角色作为一个数组传递,所以我使用[role]
在客户端,当用户注册时:
var role = $(event.target).find('#role').val();
/*
* Add account - Client-Side
*/
Accounts.createUser(account, (error) => {
if (error) {
console.log(error);
} else {
// server-side call to add the user to the role
// notice Meteor.userId() and [role]
Meteor.call('assignUserToRole', Meteor.userId(), [role]);
// everything went well, redirect to home
FlowRouter.go('home');
}
});
在我们的流星方法中(我使用lodash intersect方法验证我希望用户选择的角色)
Meteor.methods({
// when a account is created make sure we limit the roles
assignUserToRole: (userId, roles) => {
check(userId, String);
check(roles, Array);
var allowedRoles = ['student', 'parent', 'teacher'];
if (_.intersection(allowedRoles, roles).length > 0) {
Roles.addUsersToRoles(userId, roles, 'user');
} else {
Roles.addUsersToRoles(userId, ['student'], 'user');
}
}
});