Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 保护我的非规范化流星评级系统_Javascript_Mongodb_Security_Meteor_Denormalization - Fatal编程技术网

Javascript 保护我的非规范化流星评级系统

Javascript 保护我的非规范化流星评级系统,javascript,mongodb,security,meteor,denormalization,Javascript,Mongodb,Security,Meteor,Denormalization,这里有一个很难(对我来说)且冗长的问题: 我要接受整个Mongo非规范化的事情。我创建了一个分级系统,用户在其中对彼此的视频进行分级。要获得视频的平均分数,每次用户“查看”视频文档时(使用meteor.methods upsert),将0到10之间的数字直接添加到视频文档中的分数字段(在名为“条目”的集合中)。当然,条目的平均分数是所有评分的总和除以评论总数。无论如何,我都会将每次评论记录在一个单独的集合中 我的问题是。。。我不知道如何安全地写这个。没有什么可以阻止某人向总和中添加大于10或小于

这里有一个很难(对我来说)且冗长的问题:

我要接受整个Mongo非规范化的事情。我创建了一个分级系统,用户在其中对彼此的视频进行分级。要获得视频的平均分数,每次用户“查看”视频文档时(使用meteor.methods upsert),将0到10之间的数字直接添加到视频文档中的分数字段(在名为“条目”的集合中)。当然,条目的平均分数是所有评分的总和除以评论总数。无论如何,我都会将每次评论记录在一个单独的集合中

我的问题是。。。我不知道如何安全地写这个。没有什么可以阻止某人向总和中添加大于10或小于0的数字(或重复添加可接受的数字)

你能帮忙吗?也许如果我说“如果你试图更新评论总数的新数字(在条目文档中)不等于该条目在评论集合中存储的所有评论的总和…加上你的最新分数,那么抛出一个错误。”但是如果这是正确的,那怎么写呢

以下是共享客户端/服务器代码:

//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 review. Check your email inbox.")
    }
    if (Meteor.user().status === "suspended") {
      throw new Meteor.Error(403, "Cannot perform this action while account is suspended.")
    }
    var review = Reviews.findOne(id);
    if (review && doc.reviewer !== this.userId) {
      throw new Meteor.Error(403, "You don't own that review.");
    }
    if (doc.reviewer !== 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);
  }
});

//update entry score
Meteor.methods({
    entryScoreUpdate: function(id, doc) {
        Entries.update(id, doc);
    }
});
以下是相关的客户端代码:

  Meteor.call('reviewUpsert',
    Reviews.findOne({unique_review: reviewer_and_entry}, {}, function(err, result){
      if (result) {
        return result._id;
      }
      if (!result) {
        return null;
      }
    }),
    {date: new Date(), reviewer: Meteor.userId(), entry: Session.get('entryId'), title: entrytitle.title, unique_review: reviewer_and_entry, reviewername: Meteor.user().username, review: reviewfield, score: parseInt(scorefield)}, function(err){
      if (err)
        Alerts.add('Review error: ' + err.reason, 'warning');
      else {
          var reviewAdd = parseInt(scorefield) - lastscore;
          Meteor.call('entryScoreUpdate',         
            {_id: Session.get('entryId')}, {$inc: {reviewsum: reviewAdd, reviewcount: incCount}},
            function(err){
              if (err)
                Alerts.add('Review error: ' + err.reason, 'warning');
              else {
                  var entryforavg = Entries.findOne(Session.get('entryId'));
                  Meteor.call('entryScoreUpdate',         
                    {_id: Session.get('entryId')}, {$set: {avgScore: Number(((entryforavg.reviewsum/entryforavg.reviewcount)*10).toFixed(2))}},
                    function(err){
                      if (err)
                        Alerts.add('Review error: ' + err.reason, 'warning');
                      else {
                        Alerts.add('Review has been updated.', 'success'),
                        Session.set("formStatus", 'oldForm');
                      }
                    }
                  );
              }
            }
          );
      }
    }
  ); 
这个怎么样:

Meteor.methods({
    reviewUpsert : function(id, doc){
        ...
        if( (doc.rating > 10) || (doc.rating < 0) ){
            throw new Meteor.Error( ... )
        }
    }
})
Meteor.methods({
reviewUpsert:功能(id,文档){
...
如果((文件评级>10)| |(文件评级<0)){
抛出新流星。错误(…)
}
}
})

至于阻止同一用户重复输入评级,你必须跟踪哪些用户对哪些视频进行了评级并更新他们的评级,而不是盲目地添加新的评级。

我终于找到了答案。我不需要将entries.update作为自己的Meteor.method在客户端上调用。我可以在服务器上通过“ReviewUpsert”方法运行Entries.update。这样的话,我就不会给用户提供编辑其他用户视频的权限。他们只需编辑评论,服务器就可以编辑视频的平均值。

谢谢这一部分。我在上面的代码中跟踪用户评分,但是为了得到一个平均值并显示这些平均值的反应列表,我必须在视频文档中复制它。要做到这一点,我必须允许用户访问视频文档。这就是安全问题开始的地方。除非你要在视频文档中的数组中存储每个分级,而不是仅仅为分级创建一个集合。也许在分级集合中,你还可以包含与每个分级关联的用户名?这通常是我在白板上做标记,找出哪种解决方案最糟糕的时候