【问题标题】:Prevent client from calling server-side methods阻止客户端调用服务器端方法
【发布时间】:2015-08-08 01:43:24
【问题描述】:

所以我有一个接受用户名和密码的登录表单。当输入用户名/密码并单击提交时,第一步是检查帐户是否存在并已启用。我已经使用下面的代码实现了这一点。问题是,执行检查的服务器端方法is_user_enabled 可以由客户端通过浏览器控制台访问。通常我可以通过这样做来防止这种情况:

my_method : function(doc) {
    if (is_admin()) {
        // Only admins can run this method.
    }
}

但在is_user_enabled 的情况下,用户尚未登录。那么,我的问题是,处理这种情况的正确方法是什么?

我的代码:

client/login.html

{{#autoForm schema=get_login_form_schema id="login_form"}}
    {{> flashMessages}}
    <fieldset>
        <!-- <legend>Create User</legend> -->
        {{> afQuickField name="username" placeholder="schemaLabel" label=false}}
        {{> afQuickField name="password" placeholder="schemaLabel" type="password" label=false}}
        <div>
            <button type="submit" class="btn btn-primary">Login</button>
        </div>
    </fieldset>
{{/autoForm}}

client/lib/helpers.js

AutoForm.hooks({
    login_form: {
        onSubmit: function (insert_doc, update_doc, current_doc) {
            Meteor.call("is_user_enabled", insert_doc, function(error, result) {
                if (result) {
                   // Try to log user in via Meteor.loginWithPassword()
                 }
            });
         }
    }
});

server/lib/methods.js

Meteor.methods({
    is_user_enabled : function(doc) {
        // Used by the login form. Returns true if user exists and account is enabled.
        check(doc, schemas.login);
        var user = Meteor.users.findOne({username: doc.username}, {fields: {status: 1}});
        if (user.status === "enabled") {
            return true;
        }
    }
});

最终解决方案

client/lib/helpers.js

AutoForm.hooks({
    login_form: {
        onSubmit: function (insert_doc, update_doc, current_doc) {
            Meteor.loginWithPassword(insert_doc.username, insert_doc.password, function(error) {
                // Called with no arguments on success
                // or with a single Error argument on failure.
                if (error) {
                    FlashMessages.sendError(error);
                    this.done();
                } else {
                    // Successful login. Redirect to /.
                    this.done();
                    Router.go('/');
                }
            });
            return false;  // Prevent browser submit event.
        },
    }

server/lib/permissions.js

Accounts.validateLoginAttempt(function (info) {
    if (info.user && info.user.status === "enabled") {
        return true;
    } else {
        throw new Meteor.Error("Invalid credentials.");
    }
});

更多关于[Accounts.validateLoginAttempt][1]的信息

【问题讨论】:

    标签: meteor


    【解决方案1】:

    您无法阻止客户端调用服务器方法。您对 is_user_enabledis_admin 的检查需要在您的服务器方法以及客户端上进行。您当然可以在您的 methods.js 文件中拥有只有服务器上的方法才能访问的私有函数。更多提示见http://0rocketscience.blogspot.com/2015/07/meteor-security-no-1-meteorcall.html

    【讨论】:

      【解决方案2】:

      是的,您可以阻止 Meteor 方法从客户端执行。 this.connection 只会在从客户端调用时设置在方法中。从服务器调用时,它将为空。使您可以执行以下操作:

      serverOnlyMethod: function () {
          if(this.connection) throw(new Meteor.Error(403, 'Forbidden.'));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-09
        • 2011-03-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-08
        • 2011-08-30
        相关资源
        最近更新 更多