Javascript 无法使用';角色';包裹
我试图使用Atmosphere上提供的“roles”包,但无法将其用于Accounts.onCreateUser(),我可以在github上获得示例。当我注册一个用户时,我想给他们添加一个角色,当我测试是否分配了这个角色时,它不会选择它 这是我的密码 /server/users.jsJavascript 无法使用';角色';包裹,javascript,meteor,roles,atmosphere,Javascript,Meteor,Roles,Atmosphere,我试图使用Atmosphere上提供的“roles”包,但无法将其用于Accounts.onCreateUser(),我可以在github上获得示例。当我注册一个用户时,我想给他们添加一个角色,当我测试是否分配了这个角色时,它不会选择它 这是我的密码 /server/users.js Accounts.onCreateUser(function(options, user){ var role = ['admin']; Roles.addUsersToRoles(user, role);
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");
}
}
});
如果查看
角色
包中使用的代码,您将看到他们使用传入的用户/userId对用户集合执行查询(,从第623行开始):
由于在将用户对象插入集合之前调用了onCreateUser
(:返回的文档直接插入Meteor.users集合),角色执行查询时无法找到它
要解决此问题,必须等待用户插入集合。如果您查看角色
包,它们的所有示例都显示了这一点。例如,(第二个例子,添加了注释),以及许多其他内容:
// insert user and retrieve the id
id = Accounts.createUser({
email: user.email,
password: "apple1",
profile: { name: user.name }
});
// now we can verify that the user was inserted and add permissions
if (user.roles.length > 0) {
Roles.addUsersToRoles(id, user.roles);
}
希望这能对你的问题有所启发。因此,基本上只需插入用户,然后在之后添加权限。我不知道如何将Roles.addUsersToRoles与创建用户时调用的onCreateUser函数集成。在OnCreateUser中调用它时,它不起作用,正如您所做的,正如您所发现的。但是在用户创建循环中调用addUsersToRoles的示例案例似乎不适用于新用户创建帐户的正常用例
相反,我只是:
Accounts.onCreateUser(function(options, user){
var role = ['admin'];
user.roles = role
return user;
});
要在用户文档被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;
});
接受的答案迫使您为meteor通过帐户ui/密码给出的登录逻辑编写样板代码。
其他答案对底层实现进行了假设,超时解决方案引入了竞争条件
为什么不这样做:
Accounts.onCreateUser(函数(选项,用户){
...
Meteor.setTimeout(函数(){
Roles.addUsersToRoles(用户id、角色、组);
},0);
...
});代码>我不想重写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);
},
});
我发现这样做的方法很简单
我将角色作为数组传递,因此使用了[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');
}
});
在我们的meteor方法中(我使用lodash intersect方法来验证我希望用户选择的角色)
这里的问题实际上归结为寻找一个postcreate用户钩子(而onCreateUser
不是)
原来,这样的事情是存在的!它被称为postSignUpHook
我从这个答案中发现:
这是向使用样板UserAccounts包创建的用户添加角色的首选方法(即,如果您没有使用Accounts.createUser
)
更新
最终,我使用了matb33:collection钩子,如下所示:
只要在Meteor.startup中插入该代码,事情就会按预期进行。回答得很好。我以前见过这个问题,我愿意接受建议。也许只是在文档中特别指出这一点?@alanning谢谢!是的,那可能会引起一些混乱。我个人建议在文档中添加一些内容。即使只是在atmosphere页面的client部分之后添加注释,也可能会发现其中一些情况。否则,希望人们会开始找到与之相关的SO帖子。那么使用accounts ui创建的用户呢?@Dan,@DoctorPangloss的回答让我们使用方便的onCreateUser
。我们使用自己的自定义Meteor方法创建用户,因此在我们的应用程序中,我们按照@Firo建议的方式进行创建。我添加了一个新函数的示例,该函数直接在用户对象上设置角色,但只要角色使用的db结构保持不变(正如DP在他的一条评论中提到的)。下一版本的角色可能会使用一个标志,该标志允许您指示用户角色应直接在用户对象上更新,以便可以在onCreateUser中直接使用。没有关于什么时候会这样的计划。虽然这对角色有效,但如果你同时拥有角色和组,它就不起作用了。通常你会得到这样的结果:“角色”:{“\uuuu全局角色”\uuuuuuu:[“管理员”]},
如果“管理员”
还不在角色
集合中,这会起作用吗?这是否会将其添加到roles
集合中?与user.roles=['admin']
相比,它的优势是什么,即dojomouse的答案?@dojomouse的答案假设了allaning:roles
的工作原理。如果他们不将角色存储在字符串数组中呢?如果另一段代码修改了角色怎么办?如果您更新了角色
,而他又添加了一种方法,该怎么办?在对dojomouse解决方案的评论中,您实际上将看到一个示例,说明如果直接修改此数组,您将100%破坏某些内容。通过这种方式,您可以保证只要addUsersToRoles
不改变,您就不会做其他事情。这比Joe上面的答案复杂得多,Joe的答案不需要手动设置用户id,也不需要添加其他不必要的依赖项
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');
}
});
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');
}
}
});