访问检查meteor.methods / meteor.call

时间:2014-05-06 05:51:01

标签: javascript meteor upsert

我正在使用Meteor.methods进行upsert,但它不安全,因为可信代码避免了允许/拒绝规则。我在客户端和服务器上都运行了这两个:

//update today's topics
Meteor.methods({
  todayUpsert: function(id, doc){
     Today.upsert(id, doc);
  }
});

//update reviews
Meteor.methods({
  reviewUpsert: function(id, doc){
     Reviews.upsert(id, doc);
  }
});

第一个应该只能由admin用户访问。 第二个应该只能由文档所有者访问。

有人可以帮我弄明白怎么写吗?当我在不使用meteor.call的情况下使用允许/拒绝规则编写它时,它看起来像这样:

function adminUser(userId) {
    var adminUser = Meteor.users.findOne({username:"Quin"});
    return (userId && adminUser && userId === adminUser._id);
}

Topics.allow({
    insert: function(userId, doc){
        return adminUser(userId);
    },
    update: function(userId, doc, fields, modifier){
        return adminUser(userId);
    },
    remove: function(userId, doc){
        return adminUser(userId);
    },
    fetch: ['user']
});

Reviews.allow({
  insert: function (userId, doc) {
    // the user must be logged in, and the document must be owned by the user
    return (userId && doc.user === userId && Meteor.user().emails[0].verified === true);
  },
  update: function (userId, doc, modifier) {
    // can only change your own documents
    return (doc.user === userId && Meteor.user().emails[0].verified === true);
  },
  remove: function (userId, doc) {
    // can only remove your own documents
    return doc.user === userId;
  },
  fetch: ['user']
});

1 个答案:

答案 0 :(得分:3)

在内部方法中,this.userId是调用方法的用户的用户ID(如果他们没有登录,则为null)。您可以检查,如果不是管理员帐户,则抛出Meteor.Error

//update today's topics
Meteor.methods({
  todayUpsert: function(id, doc) {
    if (!adminUser(this.userId)) {
      throw new Meteor.Error(403, "You must be an admin to do that");
    }
    Today.upsert(id, doc);
  }
});

//update reviews
Meteor.methods({
  reviewUpsert: function(id, doc) {
    if (!this.userId) {
      throw new Meteor.Error(403, "You must be logged in to do that");
    }
    if (Meteor.users.findOne(this.userId).emails[0].verified !== true) {
      throw new Meteor.Error(403, "Your email must be verified to do that")
    }

    var review = Reviews.findOne(id);
    if (review && review.owner !== this.userId) {
      throw new Meteor.Error(403, "You don't own that review");
    }
    if (doc.owner !== this.userId) {
      throw new Meteor.Error(403, "Cannot create a review for someone else");
      // alternatively, just set doc.owner = this.userId
    }

    Reviews.upsert(id, doc);
  }
});