iron:router + alanning:roles => 为什么这个角色检查随机工作?
iron:router + alanning:roles => why this role check working randomly?
我正在使用 iron:router 和 alanning:roles,我想限制我的 SecretArea 仅供已添加到管理员角色的用户使用。如果用户未登录,这就可以正常工作。但是如果用户已登录并且她是管理员,那么麻烦就开始了。
我可以在针对 SecreArea 进行的每个页面加载中获得 Meteor.userId()。问题是 Roles.userIsInRole 有时 returns 为真,有时为假。意义不大..
对于那些知道他们应该拥有管理员权限的用户来说,这确实很烦人,而且这仍然是非常随机地路由他们。我认为这里的比例大约是 90-10%,大部分时间都有效,但十分之一的时间无效。
不确定,但这主要发生在更改代码和重新加载流星时。
SecretAreaController = RouteController.extend({
layoutTemplate: 'secretAreaLayout',
onBeforeAction: function () {
if (!Roles.userIsInRole(Meteor.userId(), ['admin']))
Router.go('/');
else
this.next();
}
});
值得一提的是:所有 SecreArea 路由都扩展了这个控制器。
我为此使用的软件包:
我是不是做错了什么,或者有更好的解决方案吗?
感谢任何帮助!
Meteor.userId()
是 reactive data source。第一次加载应用程序时,流星执行登录过程。所以你也应该检查 Meteor.loggingIn()
.
我不太了解iron:router
。你应该 if (Meteor.loggingIn()) {//wait}
在一个钩子上做类似的事情。
几个令人沮丧的小时后,这为我解决了问题。
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 的文档中说 "The currently logged-in user's roles field is automatically published to the client."。我认为这个问题存在某种时间问题,导致了这个问题。因为添加 waitOn 之后问题就消失了。
正如其他人所指出的,主要问题是角色数据在客户端可用的时间。这是我最近做的 presentation 的序列图,它说明了正在发生的事情:
解决此问题的一种方法是让路由器阻塞,直到所有数据都可用。这行得通,但不是理想的用户体验。
处理此问题的最佳方法是不在路由器中执行身份验证检查,而是在 template-level 中执行它们。 FlowRouter 强制你这样做 template-level 但 IronRouter 更宽松。 Arunoda 在他的 Meteor Routing Guide.
中对此做了很好的 write-up
这里有几个例子显示了 template-level 身份验证的作用:
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。
我正在使用 iron:router 和 alanning:roles,我想限制我的 SecretArea 仅供已添加到管理员角色的用户使用。如果用户未登录,这就可以正常工作。但是如果用户已登录并且她是管理员,那么麻烦就开始了。
我可以在针对 SecreArea 进行的每个页面加载中获得 Meteor.userId()。问题是 Roles.userIsInRole 有时 returns 为真,有时为假。意义不大..
对于那些知道他们应该拥有管理员权限的用户来说,这确实很烦人,而且这仍然是非常随机地路由他们。我认为这里的比例大约是 90-10%,大部分时间都有效,但十分之一的时间无效。
不确定,但这主要发生在更改代码和重新加载流星时。
SecretAreaController = RouteController.extend({
layoutTemplate: 'secretAreaLayout',
onBeforeAction: function () {
if (!Roles.userIsInRole(Meteor.userId(), ['admin']))
Router.go('/');
else
this.next();
}
});
值得一提的是:所有 SecreArea 路由都扩展了这个控制器。
我为此使用的软件包:
我是不是做错了什么,或者有更好的解决方案吗?
感谢任何帮助!
Meteor.userId()
是 reactive data source。第一次加载应用程序时,流星执行登录过程。所以你也应该检查 Meteor.loggingIn()
.
我不太了解iron:router
。你应该 if (Meteor.loggingIn()) {//wait}
在一个钩子上做类似的事情。
几个令人沮丧的小时后,这为我解决了问题。
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 的文档中说 "The currently logged-in user's roles field is automatically published to the client."。我认为这个问题存在某种时间问题,导致了这个问题。因为添加 waitOn 之后问题就消失了。
正如其他人所指出的,主要问题是角色数据在客户端可用的时间。这是我最近做的 presentation 的序列图,它说明了正在发生的事情:
解决此问题的一种方法是让路由器阻塞,直到所有数据都可用。这行得通,但不是理想的用户体验。
处理此问题的最佳方法是不在路由器中执行身份验证检查,而是在 template-level 中执行它们。 FlowRouter 强制你这样做 template-level 但 IronRouter 更宽松。 Arunoda 在他的 Meteor Routing Guide.
中对此做了很好的 write-up这里有几个例子显示了 template-level 身份验证的作用:
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。