meteor 中的安全性(插入/更新/删除操作)的工作方式与任何其他框架中的安全性相同:在执行用户执行的操作之前,请确保用户有权执行该操作。安全性在 Meteor 中可能看起来是一个弱点,但它并没有比其他框架更受它的影响(尽管在 Meteor 中通过控制台更容易利用它)。
解决问题的最佳方法可能因情况而异,但这里有一个示例:如果用户发布帖子,则该用户应获得 5 分。这是一个不好的解决方法:
if(Meteor.isClient){
// Insert the post and increase points.
Posts.insert({userId: Meteor.userId(), post: "The post."})
Meteor.users.update(Meteor.userId(), {$inc: {'profile.points': 5}})
}
if(Meteor.isServer){
Posts.allow({
insert: function(userId, doc){
check(doc, {
_id: String,
userId: String,
post: String
})
// You must be yourself.
if(doc.userId != userId){
return false
}
return true
}
})
Meteor.users.allow({
update: function(userId, doc, fieldNames, modifier){
check(modifier, {
$inc: {
'profile.points': Number
}
})
if(modifier.$inc['profile.points'] != 5){
return false
}
return true
}
})
}
是什么让它变得糟糕?用户可以在不发布帖子的情况下增加他的积分。这是一个更好的解决方案:
if(Meteor.isClient){
// Insert the post and increase points.
Method.call('postAndIncrease', {userId: Meteor.userId(), post: "The post."})
}
if(Meteor.isServer){
Meteor.methods({
postAndIncrease: function(post){
check(post, {
userId: String,
post: String
})
// You must be yourself.
if(post.userId != this.userId){
return false
}
Posts.insert(post)
Meteor.users.update(this.userId, {$inc: {'profile.points': 5}})
}
})
}
更好,但仍然很糟糕。为什么?由于延迟(帖子是在服务器上创建的,而不是在客户端上创建的)。这是一个更好的解决方案:
if(Meteor.isClient){
// Insert the post and increase points.
Posts.insert({userId: Meteor.userId(), post: "The post."})
}
if(Meteor.isServer){
Posts.allow({
insert: function(userId, doc){
check(doc, {
_id: String,
userId: String,
post: String
})
// You must be yourself.
if(doc.userId != userId){
return false
}
return true
}
})
Posts.find().observe({
added: function(post){
// When new posts are added, the user gain the points.
Meteor.users.update(post.userId, {$inc: {'profile.points': 5}})
}
})
}
此解决方案的唯一缺点是积分增量的延迟,但这是我们必须忍受的(至少目前是这样)。在服务器上使用观察也可能是一个缺点,但我认为你可以通过使用包收集钩子来传递它。