Security 确保从客户端访问集合';s侧
我有一个meteor应用程序原型,运行良好,但目前还非常不安全:我需要显示与当前登录用户匹配的用户列表。首先,我决定发布所有用户,将字段限制为筛选客户端用户列表所需的字段Security 确保从客户端访问集合';s侧,security,meteor,publish-subscribe,Security,Meteor,Publish Subscribe,我有一个meteor应用程序原型,运行良好,但目前还非常不安全:我需要显示与当前登录用户匹配的用户列表。首先,我决定发布所有用户,将字段限制为筛选客户端用户列表所需的字段 Meteor.publish('users', function () { return Meteor.users.find({}, { fields: { 'profile.picture': 1, 'profile.likes': 1, 'profile.friends':
Meteor.publish('users', function () {
return Meteor.users.find({}, {
fields: {
'profile.picture': 1,
'profile.likes': 1,
'profile.friends': 1,
'profile.type': 1
}
});
});
然后在我的路由器中,我会请求只在客户端显示我想要的内容:
Router.map(function() {
this.route('usersList', {
path: '/users',
waitOn: function () {
return Meteor.subscribe('users');
},
data: function () {
var user = Meteor.user();
return {
users: Meteor.users.find({ $and: [
{_id: {$ne : user._id}},
{'profile.type': user.profile.interest}
]})
};
}
});
});
在上面的代码中,我查询所有不是当前用户且其类型符合当前用户兴趣的用户。我还使用此客户端帮助程序在“profile.friends”数组中包含我的用户的照片上显示特定边框:
Template.userItem.helpers({
getClass: function(userId) {
var user = Meteor.user();
var lookedup = Meteor.users.findOne({_id: userId});
if ($.inArray(user._id, lookedup.profile.friends) !== -1)
return "yes";
return "no";
}
});
现在这一切都很好,但有了这个设置,每个客户端都可以查询每个用户,并获得他们的类型、图片、朋友列表和喜欢的数量。如果我在MVC中,这个信息只能在服务器端访问。所以我决定我的下一个迭代是安全的。我会将查询从路由器文件移动到发布文件。这就是麻烦开始的地方
Meteor.publish('users', function () {
var user = Meteor.users.findOne({_id: this.userId});
var interest = user.profile.interest;
// retrieve all users, with their friends for now
allUsers = Meteor.users.find({ $and: [
{'_id': {$ne: user._id}},
{'profile.type':interest}
]},
{ fields: {'profile.picture': 1, 'profile.friends': 1}}
);
return allUsers;
});
在路由器中:
Router.map(function() {
this.route('usersList', {
path: '/users',
waitOn: function () {
return Meteor.subscribe('users');
},
data: function () {
var user = Meteor.user();
return {users: Meteor.users.find({_id: {$ne : user._id}})};
}
});
});
(注意,我仍然需要将当前用户从路由器查询中排除,因为当前用户总是完全发布的)
这是可行的,但是:
Router.go('usersList')
时,用户列表不会得到更新。只有在刷新浏览器时,我的列表才会根据用户的新兴趣进行更新。不知道为什么Meteor.publish('users', function () {
var user = Meteor.users.findOne({_id: this.userId});
var interest = user.profile.interest;
// retrieve all users, with their friends for now
allUsers = Meteor.users.find({ $and: [
{'_id': {$ne: user._id}},
{'profile.type':interest}
]},
{ fields: {'profile.picture': 1, 'profile.friends': 1}}
);
// ------------- ADDED ---------------
allUsers.forEach(function (lookedup) {
if (_.contains(lookedup.profile.friends, user._id))
lookedup.profile.relation = "yes";
else
lookedup.profile.relation = "no";
lookedup.profile.friends = undefined;
return lookedup;
});
// ------------- END ---------------
return allUsers;
});
显然,这段代码根本不起作用,因为我无法修改foreach循环中的游标值。但它给出了一个我想要实现的想法:让客户端知道一个朋友是否匹配,而不让客户端访问所有用户的朋友列表。(同时,避免在显示过程中每个用户都必须执行一个请求才能询问服务器此特定用户是否与此特定用户匹配)您可以添加转换函数并动态修改光标文档
1。是预期的行为,因为服务器上的发布代码是非反应性的。这篇博文可能会对你有所帮助:2。实施起来不应该太难。我认为检查用户是否在当前用户的好友列表中是一个好主意,而不是反过来检查(如果友谊是双向的)。你能把你试过的密码贴出来吗。这实际上是一个“匹配”系统,为了清晰起见,我简化了它(我认为这个问题已经够复杂了)。因此,我需要检查该用户是否在其他用户朋友中,而不允许他访问该用户的整个朋友列表。我并没有真正“尝试”一些我认为有效的东西,只是重复了一遍。不管怎样,我都会把代码放进去;)