我有以下文档结构:
ProductDocument {
_id: "a",
price: 12,
starredByUserIds: [
"user1id",
"user2id",
"user3id",
]
}
为了安全起见,我想通过客户端控制台执行查询,确保给定用户无法看到其他用户的starredByUserIds。
即。 user3应该只能看到自己的条目:
ProductDocument {
_id: "a",
price: 12,
starredByUserIds: [
"user3id",
]
}
虽然未登录的用户应该只能看到:
ProductDocument {
_id: "a",
price: 12,
starredByUserIds: [
]
}
我似乎无法定义正确的Publish命令。我喜欢能够做类似的事情:
Meteor.publish('Products', function() {
return Products.find( {}, { fields: { starredByUserIds: this.userId }} );
})
但是'fields'不接受/匹配任意字符串值。
如何实现这一目标?
答案 0 :(得分:2)
我认为以下查询应该符合您的要求:
Products.find({}, {starredByUserIds: {$elemMatch:{$eq:this.userId}});
答案 1 :(得分:1)
以下代码段可行:
Meteor.publish('Products', function() {
return Products.find( {starredByUserIds: this.UserId}, { fields: { starredByUserIds: 0 }} );
})
<强>解释强>:
此处查询选择器starredByUserIds: this.UserId
将仅返回其starredByUserIds
数组中具有当前用户ID的文档。
我在将starredByUserIds
数组发送到客户端时省略它,因为如果用户已登录,它将包含当前用户的ID,如果用户未登录则将为空in,你可以重新生成它。
答案 2 :(得分:1)
考虑到这些安全问题,您可能应该更改数据模型并将“星标”放在不同的集合中。如果您不想这样做,那么您必须将发布函数的代码更改为以下内容:
Meteor.publish('Products', function () {
return Products.find().fetch().map(function (product) {
if (this.userId && product.starredByUserIds.indexOf(this.userId) != -1) {
product.starredByUserIds = [this.userId];
} else {
product.starredByUserIds = [];
}
return product;
});
});