【问题标题】:How do you secure the client side MongoDB API?您如何保护客户端 MongoDB API?
【发布时间】:2012-04-24 07:05:22
【问题描述】:

我不希望我的所有用户都能够插入/销毁数据。

【问题讨论】:

标签: meteor


【解决方案1】:

[更新]现在有一个官方和记录的身份验证包,它提供了不同的解决方案来保护集合。

在 CRUD 级别:

[服务器] collection.allow(options) 和 collection.deny(options)。限制此集合的默认写入方法。一旦在集合上调用其中任何一个,该集合上的所有写入方法都会受到限制,而与不安全的包无关。

还有insecure删除客户端的完全写入权限。

来源:Getting Started with Auth(感谢@dan-dascalescu)


[旧答案]

显然,正在开发 Auth Package(?),它应该避免任何用户像现在一样完全控制数据库。还有人建议通过定义您自己的突变(方法)并在他们尝试执行未经授权的操作时使它们失败来提出现有的解决方案(解决方法)。我没有得到更好的结果,但我认为这通常是必要的,因为我怀疑 Auth 包是否会让您在行级别上实现通常的身份验证逻辑,但可能只在 CRUD 方法上。得看看开发者怎么说。

[编辑] 发现了一些似乎证实了我的想法的东西:

目前,客户端被授予对集合的完全写入权限。他们可以执行任意 Mongo 更新命令。一旦我们建立了身份验证,您将能够限制客户端对插入、更新和删除的直接访问。我们也在考虑验证器和其他类似 ORM 的功能。

这个答案的来源:

Accessing to DB at client side as in server side with meteor

https://stackoverflow.com/questions/10100813/data-validation-and-security-in-meteor/10101516#10101516

【讨论】:

【解决方案2】:

虽然还没有记录在案的方法可以做到这一点,但这里有一些代码可以满足您的需求:

Foo = new Meteor.Collection("foo");
...
if (Meteor.is_server) {
   Meteor.startup(function () {
       Meteor.default_server.method_handlers['/foo/insert'] = function () {};
       Meteor.default_server.method_handlers['/foo/update'] = function () {};
       Meteor.default_server.method_handlers['/foo/remove'] = function () {};
   });
}

这将禁用默认的插入/更新/删除方法。客户端可以尝试插入到数据库中,但是服务器什么也不做,当服务器响应时客户端会注意到并删除本地创建的项目。

insert/update/remove 仍然可以在服务器上运行。您需要使用在服务器上运行的 Meteor.methods 方法来完成任何数据库写入。

当身份验证分支登陆时,所有这一切都会改变。一旦发生这种情况,您将能够提供验证器来检查和授权服务器上的数据库写入。这里有更多细节:http://news.ycombinator.com/item?id=3825063

【讨论】:

  • 太好了,感谢您提供的所有信息!迫不及待地想看到这个成熟。
  • 是否也可以保护集合不被客户端读取?
  • 没关系;只需删除自动发布。 meteor remove autopublish
  • Meteor 0.5.0 及更高版本不需要此技术。使用allowdeny
【解决方案3】:

更简洁的方式:

_.each(['collection1', 'collection2'], function(collection){
    _.each(['insert','update', 'remove'], function(method){
      Meteor.default_server.method_handlers['/' + collection + '/' + method] = function(){}
    });
});

或者让它更地道:

扩展流星:

_.extend(Meteor.Collection.prototype, {
  remove_client_access: function(methods){
    var self = this;
    if(!methods) methods = ['insert','update','remove'];
    if(typeof methods === 'String') methods = [methods];
    _.each(methods, function(method){
      Meteor.default_server.method_handlers[self._prefix + method] = function(){}
    });
  }
});

调用更简单:

List.remove_client_access() // restrict all
List.remove_client_access('remove') //restrict one
List.remove_client_access(['remove','update']) //restrict more than one

【讨论】:

  • 只是想说这不再是必要的,因为 v0.5.0 引入了身份验证。见docs.meteor.com/#accounts_api。 @greg:你有机会更新你的答案吗?
【解决方案4】:

我是 Meteor 的新手,但到目前为止我遇到的就是这两点

  1. 您可以通过在服务器端publish 命令的find 命令中添加参数来限制客户端可以访问数据库的内容。然后当客户端调用Collection.find({})时,返回的结果对应于服务器端的结果,例如Collection.find({user: this.userId})(另见Publish certain information for Meteor.users and more information for Meteor.userhttp://docs.meteor.com/#meteor_publish

  2. 内置的一件事(我有流星 0.5.9)是客户端只能通过 id update 项目,而不是使用选择器。如果有不符合要求的尝试,则会将错误记录到客户端的控制台。 403: "Not permitted. Untrusted code may only update documents by ID."(见Understanding "Not permitted. Untrusted code may only update documents by ID." Meteor error)。

鉴于第 2 点,您需要在服务器端使用Meteor.methods 以使具有Meteor.call 的客户端可以使用远程过程调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 2017-10-18
    • 2013-11-29
    • 2011-11-09
    • 1970-01-01
    • 2017-06-29
    相关资源
    最近更新 更多