Meteor 中的安全方法

Posted

技术标签:

【中文标题】Meteor 中的安全方法【英文标题】:Safe Methods in Meteor 【发布时间】:2014-12-07 11:25:08 【问题描述】:

我正在使用 Meteor 开发一个消息传递应用程序。出于安全原因,我禁用了从客户端调用的任何插入/更新/删除。现在插入消息的唯一方法是使用方法。

Meteor.methods(
  sendMessage: function (text) 
    Messages.insert( userId: Meteor.userId(), roomId: Rooms.findOne()._id, name: Meteor.users.find(Meteor.userId()).fetch()[0].profile.name , message: text );
  
);

这种方法只询问消息的内容,因此用户无法使用其他名称调用该方法或尝试将相同的消息发送到其他聊天室。

我是使用 Meteor 的初学者,所以我想知道,在服务器上运行的真实方法(不是 Stub)不会从 userId 和 roomId 获得不同的值吗?服务器上的 Rooms.findOne()._id 可以是 db 上的任何随机房间文档,以及 userId 任何用户。

如果是这种情况,我将不得不在函数中包含额外的参数,这会使其安全性大大降低。

我可能不了解这里的方法。

【问题讨论】:

【参考方案1】:

你在正确的轨道上。使用Rooms.findOne() 在服务器上当然没有意义,坦率地说,在客户端上也不是那么好(如果您发布的房间超过一个房间,这将打破)。您需要将消息和房间 ID 都传递给您的方法。该方法应验证插入是否有意义。例如,该用户当前是否房间。假设在room.members 中跟踪,sendMessage 可以按如下方式实现:

Meteor.methods(
  sendMessage: function(message, roomId) 
    check(message, String);
    check(roomId, String);

    if (!this.user)
      throw new Meteor.Error(401, 'You must be logged in.');

    if (_.isEmpty(message))
      throw new Meteor.Error(403, 'Message must not be empty.');

    var room = Rooms.findOne(roomId);

    if (!room)
      throw new Meteor.Error(404, 'Room not found.');

    if (!_.contains(room.members, this.userId))
      throw new Meteor.Error(403, 'You are not in the room.');

    var name = Meteor.user().profile.name;

    return Messages.insert(
      userId: this.userId,
      roomId: roomId,
      name: name,
      message: message
    );
  
);

并非所有这些检查都是必需的,但此示例应该让您了解方法可以提供的丰富验证集。

【讨论】:

以上是关于Meteor 中的安全方法的主要内容,如果未能解决你的问题,请参考以下文章

计算 Meteor 中帖子中的评论数

如何从Meteor.js中的方法内部的方法返回错误

如何从 Meteor 中的服务器调用客户端方法?

Meteor/Blaze - 参数中的简单字符串连接

Meteor 客户端在服务器方法中调用 findOne

Meteor 同步方法调用