我知道我可以使用方法存根来模拟数据库操作,然后才真正在服务器上运行,如@Akshat解释in this excellent answer
我想知道我是否可以而且应该使用存根来确保用户有权在不涉及任何数据库操作时执行操作(例如显示编辑按钮)。
请注意,我不想使用alanning:roles包,我想了解它是如何工作的,以及是否可以按如下方式完成:
假设我想检查管理员权限。每个用户文档都有一个roles
字符串数组字段,用于存储用户的全局权限,即user
,admin
,superadmin
等。
我在Users
文件夹中声明我的lib
集合,可供客户端和服务器使用:
let Users = Meteor.users
export default Users
我创建了一个方法存根来检查客户端上的管理员权限(它位于客户端文件夹中):
Meteor.methods({
UserIsAdmin = function () {
console.log(this.isSimulation) //Will be true
let user = Users.findOne({_id: Meteor.userId()})
return !!(user && user.roles && user.roles.indexOf('admin') != -1)
}
});
在服务器文件夹中,我将创建一个真正的方法来调用下面写的内部服务器函数(请注意,在这种情况下,我可以将userId
设置为参数):
import Users from '/imports/user/lib/user_collection.js'
Meteor.methods({
UserIsAdmin = function () {
console.log(this.isSimulation) //Will be false
return Users.isAdmin()
}
});
Users.isAdmin = function (userId=Meteor.userId()) {
var user = Users.findOne({_id: userId})
return !!(user && user.roles && user.roles.indexOf('admin') != -1)
};
现在假设我的UI上有一个编辑按钮,我会根据UserIsAdmin
方法的结果显示它。以下是问题:
role
数组),但我们在加载路由之前检查方法:路由及其UI将被加载,对吧?没有回滚?当然,由于发布不会返回任何内容,因此不会填充UI。答案 0 :(得分:1)
我不认为这在额外的安全性方面真的会给你带来太大的好处。您已经基于管理员权限隐藏了管理员UI,然后您在服务器端阻止了假管理员的任何管理员操作。据推测,您也没有将管理员数据发布给非管理员。
即使您让用户很难查看管理员屏幕,他们仍然可以看到创建它的源以及它调用的方法。他们最终可以对管理系统控制的内容进行逆向工程。
如果将管理界面捆绑在一起并提供给非管理员用户,则完全可以完全隐藏它。常见的模式是在单独的主机或端口上创建第二个管理应用程序,只能由管理员访问。管理员应用程序连接到同一个mongo数据库,因此可以控制消费者应用程序的哪些用户可以执行。
您给攻击者的一些最大线索是您使用的角色名称(admin,superadmin)。搜索已发布的“管理员”流星代码太简单,并获得有关正在发生的有趣事情的线索。方法名称也很容易被挑选出来,因为它们不会被缩小和混淆,请仔细选择。
答案 1 :(得分:1)
您的代码取决于Meteor方法的返回值,但您有一个客户端和服务器端返回值。幸运的是,它很好地定义了你会得到哪一个:
Meteor.call()
中有回调,则call
函数不返回任何内容,并且将使用服务器端返回值调用回调函数。 / LI>
Meteor.call()
没有回调,那么您将同步获得客户端返回值。无论哪种方式,您只会看到其中一个返回值。它不像订阅,其值将以某种方式稍后同步。请参阅此处的文档:http://docs.meteor.com/#/full/meteor_call
并回答你的问题:
除了数据库操作之外,您可以使用服务器端方法调用执行各种操作,例如使用密钥访问第三方REST API,启动后台操作等。
alanning:roles
包的工作方式是通过订阅保持同步的roles
集合。他们的Roles.userIsInRole
函数不是Meteor方法,而是查询此集合的简单函数调用。