我正在使用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任何用户。
如果是这种情况,我将不得不在函数中包含额外的参数,这会使安全性降低。
我可能在这里不了解方法。
答案 0 :(得分:4)
你走在正确的轨道上。使用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
});
}
});
并非所有这些检查都是必要的,但是此示例应该让您了解方法可以提供的丰富验证集。