我正在使用铁:路由器和alanning:角色,我想仅为已添加到管理员角色的用户限制我的 SecretArea 。如果用户没有登录,这可以正常工作。但是如果用户已经登录并且她是管理员,则麻烦就开始了。
我可以在针对 SecreArea 的每个页面加载上获得Meteor.userId()。问题是 Roles.userIsInRole 有时会返回true,有时会返回false。它没有多大意义..
对于那些知道他们应该拥有管理员权限的用户而言,这真的很烦人,但这仍然是随机地路由它们。我认为这里的比例大约是90-10%,大部分时间都在工作,但有一次不是十分之一。
不确定,但是当对代码和流星重新加载进行更改时,这可能会发生。
SecretAreaController = RouteController.extend({
layoutTemplate: 'secretAreaLayout',
onBeforeAction: function () {
if (!Roles.userIsInRole(Meteor.userId(), ['admin']))
Router.go('/');
else
this.next();
}
});
值得一提的是:所有SecreArea路由都在扩展这个控制器。
我正在使用的套餐:
我在这里做错了什么,或者有更好的解决方案吗?
任何帮助表示赞赏!
答案 0 :(得分:4)
经过几个小时的挫折后,这解决了我的问题。
SecretAreaController = RouteController.extend({
layoutTemplate: 'secretAreaLayout',
waitOn: function () {
return [ Meteor.subscribe("roles") ];
},
onBeforeAction: function () {
if (!Roles.userIsInRole(Meteor.userId(), ['admin']))
Router.go('/');
else
this.next();
}
});
在服务器端出版物:
Meteor.publish("roles", function (){
return Meteor.roles.find({});
});
在alanning:roles的文档中说“当前登录用户的角色字段会自动发布到客户端。”我认为这个问题存在某种时间问题,导致了这个问题。因为在添加waitOn后问题就消失了。
答案 1 :(得分:0)
Meteor.userId()
是reactive data source。当第一次应用加载时,meteor执行登录过程。因此,您还应该检查Meteor.loggingIn()
。
我不太了解iron:router
。你应该在其中一个钩子上做if (Meteor.loggingIn()) {//wait}
类似的东西。
答案 2 :(得分:0)
正如其他人所指出的,主要问题是角色数据何时在客户端上可用。这是我最近presentation所做的序列图,它说明了正在发生的事情:
解决此问题的一种方法是让路由器阻塞,直到所有数据都可用。这可行,但它不是一个理想的用户体验。
处理此问题的最佳方法是不在路由器中执行身份验证,而是在模板级别执行验证。 FlowRouter强制你做模板级但IronRouter更宽松。 Arunoda在他的Meteor Routing Guide中做了很好的写作。
以下是一些显示模板级身份验证的示例:
https://github.com/alanning/meteor-roles/tree/master/examples/flow-router
https://github.com/alanning/meteor-roles/tree/master/examples/flow-router-advanced
这些示例使用FlowRouter,但同样的原则可以很容易地应用于IronRouter。