Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.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
使投票系统安全Meteor.方法_Meteor_Meteor Methods - Fatal编程技术网

使投票系统安全Meteor.方法

使投票系统安全Meteor.方法,meteor,meteor-methods,Meteor,Meteor Methods,我正在尝试实现一个安全的投票系统,它不能通过客户端控制台的Meteor.call()进行更改。每个人都可以在登录后上下投票。但对于每个用户和帖子,每次只需一次 就我的客户而言,我得到了这样的东西: Template.postArgument.events({ 'click .yes':function() { if(Meteor.user()) { var postId = Arguments.findOne({_id:this._id}) var

我正在尝试实现一个安全的投票系统,它不能通过客户端控制台的Meteor.call()进行更改。每个人都可以在登录后上下投票。但对于每个用户和帖子,每次只需一次

就我的客户而言,我得到了这样的东西:

Template.postArgument.events({
 'click .yes':function() {
       if(Meteor.user()) {
        var postId = Arguments.findOne({_id:this._id})
        var currentArgumentId = this._id;
        if($.inArray(Meteor.userId(), postId.votedUp) ===-1) {
          if($.inArray(Meteor.userId(), postId.votedDown) !==-1) {
            Meteor.call('argumentVoteYes',currentArgumentId);
          } else {
            Meteor.call('argumentVoteYesElse',currentArgumentId);
          } 
        } else {
          Meteor.call('argumentVoteYesElseElse',currentArgumentId);
        }
      }
    }}
)};
在我的服务器上:

    Meteor.methods({
    'argumentVoteYes':function(currentArgumentId){
        Arguments.update(currentArgumentId, {
            $pull: {votedDown: Meteor.userId()},
            $inc: {score: 2 },
                $addToSet: {votedUp: Meteor.userId() }
              });
      },
      'argumentVoteYesElse':function(currentArgumentId){
        Arguments.update(currentArgumentId, {
            $inc: {score: 1 },
            $addToSet: {votedUp: Meteor.userId() }
              });
      },
      'argumentVoteYesElseElse':function(currentArgumentId){
        Arguments.update(currentArgumentId, {
            $inc: {score: -1 },
            $pull: {votedUp: Meteor.userId()}
            });
      }
    'argumentVoteNo':function(currentArgumentId){
    Arguments.update(currentArgumentId, {
        $pull: {votedUp: Meteor.userId()},
        $inc: {score: -2 },
        $addToSet: {votedDown: Meteor.userId() },
        });
  },
  'argumentVoteNoElse':function(currentArgumentId){
    Arguments.update(currentArgumentId, {
        $inc: {score: -1 },
        $addToSet: {votedDown: Meteor.userId() },
        });

  },
  'argumentVoteNoElseElse':function(currentArgumentId){
    Arguments.update(currentArgumentId, {
        $inc: {score: 1 },
        $pull: {votedDown: Meteor.userId()}
        }); 
  },
    });

问题是如何确保安全,例如,如果有人调用
Meteor.call('argumentvoteYes','someID',{$inc:{score:2})它将增加2分。如果用户两次调用此选项,投票将增加4。有什么方法可以安全地执行此操作吗?

您需要检查用户是否位于服务器上的votedUp/down阵列中。您的逻辑位于客户端右侧,因此在服务器上执行实际更新之前,只需应用相同的逻辑。

您需要检查用户是否位于服务器上的votedUp/down阵列中。您在客户端拥有逻辑,因此在服务器上执行实际更新之前,只需应用相同的逻辑。

您不必担心方法中会出现额外的增量,因为您的方法只接受一个参数。但是,您确实需要防范其他黑客:

让我们首先扩展
匹配
对象,以便检查
\u id
是否为:

Match._id = Match.Where(function(id){
  check(id, String); // first make sure we're dealing with a string
  // then grep for an exactly 17 character alphanumeric string
  return /^[a-zA-Z0-9]{17,17}/.test(id); 
});

现在让我们看一下您的第一种方法:

Meteor.methods({
  'argumentVoteYes':function(currentArgumentId){
    check(currentArgumentId,Match._id); // will error if not an _id

    var post = Arguments.findOne({ _id: currentArgumentId });
    var userId = Meteor.userId(); // the current user

    if ( post && userId ){ // make sure a real user is operating on an actual document
      // only update if no votes have been recorded OR
      // user hasn't already voted

      if ( !post.votedUp || post.votedUp.indexOf(userId) === -1 ){ 
        Arguments.update(currentArgumentId, {
          $pull: { votedDown: userId },
          $inc: { score: 2 },
          $addToSet: {votedUp: userId }
        });
      }
    }
  },

您不必担心方法会有额外的增量,因为您的方法只接受一个参数。但是,您确实需要防范其他黑客:

让我们首先扩展
匹配
对象,以便检查
\u id
是否为:

Match._id = Match.Where(function(id){
  check(id, String); // first make sure we're dealing with a string
  // then grep for an exactly 17 character alphanumeric string
  return /^[a-zA-Z0-9]{17,17}/.test(id); 
});

现在让我们看一下您的第一种方法:

Meteor.methods({
  'argumentVoteYes':function(currentArgumentId){
    check(currentArgumentId,Match._id); // will error if not an _id

    var post = Arguments.findOne({ _id: currentArgumentId });
    var userId = Meteor.userId(); // the current user

    if ( post && userId ){ // make sure a real user is operating on an actual document
      // only update if no votes have been recorded OR
      // user hasn't already voted

      if ( !post.votedUp || post.votedUp.indexOf(userId) === -1 ){ 
        Arguments.update(currentArgumentId, {
          $pull: { votedDown: userId },
          $inc: { score: 2 },
          $addToSet: {votedUp: userId }
        });
      }
    }
  },

我以前也这么想过,我发现了一个解决方案,就是只使用一个用户ID数组,而不是从客户端传递(只保存当前用户的ID)并计算数组中的总ID。它不会两次添加相同的ID

从我的代码中(您可以执行其余的检查,如用户是否在Dislike数组中,是否执行某些操作等):

在我的助手中:

likeCount: function() {
    return this.likers.length
}

我以前也这么想过,我发现了一个解决方案,就是只使用一个用户ID数组,而不是从客户端传递(只保存当前用户的ID)并计算数组中的总ID。它不会两次添加相同的ID

从我的代码中(您可以执行其余的检查,如用户是否在Dislike数组中,是否执行某些操作等):

在我的助手中:

likeCount: function() {
    return this.likers.length
}

是的,但我不知道如何获取Meteor.userId()的数组值?类似于db.arguments.find({u id:currentArgumentId……?});我必须检查数组是否为Meteor.userId();已经存在,但如何获取值?我尝试了类似于
var votedUpMeteorUser=Arguments.findOne(currentArgumentId)的方法;如果(Meteor.userId()!=null&&votedupmeteouser.votedUp!=Meteor.userId())
{….}但这不起作用,您应该在服务器上使用这个.userId。是的,但我不知道如何获取Meteor.userId()的数组值?类似于db.arguments.find({u id:currentArgumentId……?});我必须检查数组是否为Meteor.userId();已经存在,但如何获取值?我尝试了类似于
var votedUpMeteorUser=Arguments.findOne(currentArgumentId)的方法;如果(Meteor.userId()!=null&&votedupmeteouser.votedUp!=Meteor.userId())
{….}但这不起作用,你应该在服务器上使用这个.userId。嘿,米歇尔!我尝试了你的建议,如果我使用
userId=Meteor.userId(),它对我有效为什么它不使用
var userId=this.userId()???谢谢你的帮助!如果我尝试为第二次调用
argumentVoteYesElse
实现相同的逻辑,我将得到一个
无法调用未定义的方法'indexOf'的错误。我猜这是因为我在创建新帖子时没有插入votedUp??。当有人第一次点击一篇新文章并想投票支持这篇文章时,会出现错误消息。因此,在尝试post.votedUp.indexOf(userId)时没有votedUp。我现在该怎么办??我现在已经为帖子添加了投票否决按钮。如果第一次点击voteDown,然后切换到voteUp,同样会出现问题。我想现在的问题在于我的逻辑。因为现在我可以在控制台中调用“voteUpYes”
。我的分数增加2,并且设置了
votedUp:Meteor.userId()
。在此之后,我可以调用
'voteyeselselse'
并减少计数器1,并且
votedUp:Meteor.userId()
被删除。然后我可以再次调用
“voteUpYes”
,以此类推。没有限制。。这个问题真的把我搞糊涂了=/除了注意到你需要对称性之外,我不确定我能帮你什么。嘿,米歇尔!我尝试了你的建议,如果我使用
userId=Meteor.userId(),它对我有效为什么它不使用
var userId=this.userId()???谢谢你的帮助!如果我尝试为第二次调用
argumentVoteYesElse
实现相同的逻辑,我将得到一个
无法调用未定义的方法'indexOf'的错误。我猜这是因为我在创建新帖子时没有插入votedUp??。当有人第一次点击一篇新文章并想投票支持这篇文章时,会出现错误消息。因此,在尝试post.votedUp.indexOf(userId)时没有votedUp。我现在该怎么办??我现在已经为帖子添加了投票否决按钮。如果第一次点击voteDown,然后切换到voteUp,同样会出现问题。我想现在的问题在于我的逻辑。因为现在我可以在控制台中调用“voteUpYes”
。我的分数增加2,并且设置了
votedUp:Meteor.userId()
。在此之后,我可以调用
'voteyeselselse'
并减少计数器1,并且
votedUp:Meteor.userId()
被删除。然后我可以再次调用
“voteUpYes”
,以此类推。没有限制。。这个问题真的把我搞糊涂了=/除此之外,我不确定我能帮你什么