Javascript Meteor:如何防止客户端访问方法

Javascript Meteor:如何防止客户端访问方法,javascript,node.js,mongodb,methods,meteor,Javascript,Node.js,Mongodb,Methods,Meteor,所有meteor方法都可以从客户端和服务器端以相同的方式调用 假设用户知道或可以预测服务器上的所有方法名,那么他就可以调用它们并使用它的结果 例如: 一种执行跨域http请求和返回响应的方法可以通过调用大量数据Meteor.call(httpLoad,“google.com”),或者如果客户端知道document _idMeteor.call(getUserData,“_jh9d3nd9sn3js”),则可以使用从mongo加载数据的方法访问数据库文档 因此,如何避免这种情况,可能有一种比Met

所有meteor方法都可以从客户端和服务器端以相同的方式调用

假设用户知道或可以预测服务器上的所有方法名,那么他就可以调用它们并使用它的结果

例如: 一种执行跨域http请求和返回响应的方法可以通过调用大量数据
Meteor.call(httpLoad,“google.com”),或者如果客户端知道document _id
Meteor.call(getUserData,“_jh9d3nd9sn3js”),则可以使用从mongo加载数据的方法访问数据库文档


因此,如何避免这种情况,可能有一种比Meteor.methods({…})

更好的方法来存储纯服务器功能,我想这一页解释了这一点:

我引用:

“更安全的方法是将这些函数移动到isServer条件,这意味着:

数据库代码将在服务器的受信任环境中执行。
用户将无法从控制台内部使用这些功能,因为用户无法直接访问服务器

在isServer条件中,写入以下内容:

Meteor.methods({
   // methods go here
});
这是我们将用于创建方法的代码块。”


等等。我希望这会有所帮助。

通过正确的应用程序设计,您不应该关心请求是通过web UI还是通过控制台窗口中键入的内容

基本上,不要在Meteor.methods中使用通用的、有滥用价值的函数,实施合理的访问控制,限制速率和/或记录任何可能出现问题的内容

Meteor.methods中定义的任何服务器端函数都可以通过访问当前用户id。此用户ID由Meteor提供,而不是客户端API参数

由于Meteor方法服务器端代码知道登录状态和用户ID,因此它可以在决定执行用户要求它执行的操作之前执行所有检查和速率限制


你们如何限制税率?我最近没有为这个寻找一个模块。在基本Meteor中,您将添加一个Mongo集合,用于仅可在服务器端访问的用户操作。在通过Meteor方法到达的每个请求上插入时间戳、特定于用户ID的数据。在完成服务器方法代码中的请求之前,请执行Mongo查找,以了解在相关时间段内此用户ID发生了多少此类操作。这是一项很小的工作,会产生一些开销,但通过服务器范围的下划线样式的去Bounce进行速率限制的替代方案会使攻击者滥用和拒绝服务的功能处于开放状态

Meteor方法被设计成可以从客户端访问,如果您不想这样,只需要在服务器上定义一个普通的javascript函数。一个真正基本的例子是:

server/server.js

someFunction = function(params) {
    console.log('hello');
}
只要它在服务器文件夹中,就无法从客户端访问该函数


对于coffeescript用户,每个文件在技术上都是一个单独的作用域,因此您必须使用
@
定义一个全局变量,例如

@someFunction = (params) ->
    console.log 'hello'
或者,如果要将函数的作用域设置为包:

share.someFunction = (params) ->
    console.log 'hello'

如果您有需要从客户端访问但仅限于管理员用户的方法,则需要在meteor方法定义的开头添加这些检查:

Meteor.methods({
    'someMethod': function(params) {
        var user = Meteor.user();
        if (user && (user.isAdmin === true)) {
            // Do something
        } else {
            throw new Meteor.Error(403, 'Forbidden');
        }
    }
});
我不打算担保这个例子的安全性——它只是一个例子——但希望它能让您了解如何保护您的方法


编辑:注意到其他答案提到使用
if(Meteor.isServer){…}
条件。请注意,如果您在客户端也可以访问的方法中执行此操作,则用户仍然可以看到您的服务器代码,即使他们无法运行它。对于您来说,这可能是一个安全问题,也可能不是一个安全问题-如果您正在使用可从客户端访问其代码的方法对任何第三方API凭据或任何类型的敏感数据进行硬编码,请务必小心。如果您不需要客户端上的方法,最好只使用普通的JS函数。如果您使用isServer条件包装整个Meteor.methods调用,则代码将仅在服务器上,但仍可从客户端调用。

正如其他答案中正确指出的那样,您的方法将始终可以从客户端访问(根据设计)。然而,有一个简单的解决方法来检查调用是来自客户端还是来自服务器。如果你做了一个

if ( this.connection == null )

如果从服务器调用该方法,则返回true。这样,您可以将方法体的执行限制为“安全”调用。

“用户将无法从控制台内部使用这些函数”,很抱歉,但是。。。他们将能够。哎呀,那页面一定是弄错了,对不起!你们都是对的,isServer包装器所做的只是在服务器上定义该方法,因此您将无法读取该方法的代码,但您仍然可以从客户端执行该方法,并从服务器返回结果。您可能在客户端上定义方法的原因是为了乐观UI,因此您可以在客户端上运行该方法的简化版本,并立即更新UI/minimongo,但服务器将返回真实结果,如果不匹配,minimongo/UI将更新以反映这一点。这很有趣,听起来像是在线游戏编程,玩家在游戏中得到即时反应,然后他的计算最终被服务器结果纠正。Meteor方法可以很容易地与回调链接起来,这可能不适用于常规函数,因为“代码必须在光纤中运行”。到目前为止,这是最好的答案;)这取决于你想要达到的目标。据我所知,如果在服务器上使用方法回调,那么只会返回“undefined”。该方法的其余部分将运行,但不会返回结果。如果需要返回某些内容,则需要同步运行该方法(例如,不使用