我必须在Collection.allow和Collection.deny中涵盖哪些逻辑以确保它是安全的?

时间:2014-02-23 13:31:09

标签: meteor

所以刚刚开始玩Meteor并尝试绕过安全模型。似乎有两种方法可以修改数据。

Meteor.call方式似乎非常标准 - 几乎只是通过实现自己的一套业务规则来调用服务器。

然后是Collection.allow方法,它与我之前做过的任何事情都有所不同。所以看来如果你把一个collection.allow,你说客户端可以对该集合进行任何写操作,只要它可以通过其allow函数中的验证。

这让我感到不安,因为它感觉很自由,我的允许功能需要很长时间,以确保它足够安全地锁定。

例如,mongodb没有架构,因此您必须基本上有一个规则来定义哪些字段将被接受以及这些字段必须的格式。

您是否还必须为可能对您的系统进行的每种类型的更新添加业务逻辑。

所以说,我有一个SoccerTeam系列。我可能需要进行一些更改,例如我添加或删除播放器,更改团队名称,团队状态已更改等。

在我看来,你必须将所有东西都放在这个庞大的功能中。这听起来像是一个激进的想法,但似乎Meteor.call方法会简单得多。

我是否以错误的方式(或错误的用例?)考虑过这个问题?有没有人有任何关于如何构建允许或拒绝函数的示例,其中列出了我可能需要在允许函数中检查的内容使我的收藏安全吗?

2 个答案:

答案 0 :(得分:3)

我常用的allow方法是:

MyCollection.allow({
    insert: false
    update: false
    remove: false
})

然后,我有处理所有插入的方法。这些方法执行类型检查和权限评估。我发现这是一个更易于维护的方法:将数据层与在客户端上运行的代码完全分离。


  

例如,mongodb没有架构,因此您必须基本上有一个规则来定义哪些字段将被接受以及这些字段必须的格式。

看看Collection2。在将文档插入Collection之前,它们在运行时支持模式检查。

答案 1 :(得分:3)

您正在遵循我在决定如何在构建Edthena时处理数据突变时使用的相同推理方法。开箱即用,meteor为您提供了进行简单权衡的工具:

  

我是否相信客户端并获得响应更快的UI(延迟补偿)?或者我是否需要严格控制数据验证,但强制客户端等待更新?

我使用后者,并且出于以下几个原因专门使用方法调用:

  1. 我知道只有一种方法可以更新我的每个系列,我晚上睡得更好。
  2. 我发现我的一些更新需要在服务器上执行才有意义的副作用(例如,对其他集合进行非规范化更新)。
  3. 目前,我们的应用程序的延迟补偿没有明显的好处。我们发现大多数写入的延迟对用户体验来说无关紧要。
  4. allowdeny规则是弱工具。它们基本上只适用于验证所有权和其他简单检查。
  5. 在我们首次投入生产时(2013年8月),这似乎是一个彻底的结论。流星文档,API和演示突出了客户端写入的使用,所以我不完全确定我做出了正确的决定。几个月后,我第一次有机会与几个流星核心开发者坐下来 - 这是他们对我的设计选择的反应总结:

      

    这似乎是一种理性的方法。延迟补偿在某些情况下非常有用,例如移动应用和游戏,但对于所有网络应用可能都不值得。它也是很酷的演示。

    所以你有它。在撰写本文时,我对生产应用程序的建议是在真正需要速度的情况下使用客户端更新,但是你不应该因为大量使用方法而感觉自己做错了。

    至于未来,我认为在1.0之后我们将开始在客户端和服务器上看到内置模式实施等内容,这将大大有助于解决我的问题。我认为Collection2是朝着这个方向迈出的重要的第一步,但我还没有以任何有意义的方式尝试过它。


    存根

    逻辑后续问题是“为什么不使用存根?”。我花了一些时间对此进行调查,但得出的结论是方法存根对我们的项目没有用,原因如下:

    1. 我喜欢将服务器代码保存在服务器上。 Stubbing要求我将所有模型代码发送到客户端或者再次选择性地重复部分代码。在一个大型应用程序中,我认为这不实际。
    2. 我发现将客户端可能运行或未运行的内容分离出来作为维护挑战所需的开销。
    3. 为了使存根除了拒绝数据库变异之外还要做任何事情,你需要有一个允许规则 - 否则你最终会有很多UI闪烁(客户端允许写入但是服务器立即使其无效)。但是有一个允许规则会破坏整个点,因为用户仍然可以从控制台写入数据库。