在Mongoose中更新/创建模型时,是否有任何理由将用户输入的数据列入白名单?

时间:2014-06-15 08:42:21

标签: node.js mongodb mongoose

我发现自己在创建或保存用户之前就这样做了:

 var data = _.pick(req.body, 'email', 'name', 'username', 'title');

但我不知道它是否真的有必要。例如,如果有人发送了salthashedPassword或该模型不支持的任何属性,会发生什么情况。它会被扔掉吗?

salthashedPassword是我架构上的虚拟属性。

如果没有白名单,假设某人在包含其他动态属性的json对象中发送,例如followers: ['fake1', 'fake2']等,这似乎很危险。如果我理解正确的话,这将完全覆盖之前添加的内容。

2 个答案:

答案 0 :(得分:3)

Web开发中的经验法则是始终清理输入。

话虽如此,Mongoose有一个选项strict

  

严格选项,确保传递给的值   我们的架构中没有指定的模型构造函数没有得到   保存到数据库。

在Mongoose 2.x中,strict的默认值为false,但在3.x严格选项现在由defult设置为true。

您可以在架构上指定它:

new Schema({ .. }, { strict: true })

您也可以在模型上覆盖它:

var Thing = db.model('Thing');
var thing = new Thing(doc, true);  // enables strict mode

虚拟属性永远不会被您提供给模型的数据覆盖。这是因为Mongoose在内部存储虚拟属性的方式。

架构中的每个属性都定义了其类型(虚拟属性具有VirtualType)。虚拟属性内部存储在与" real"不同的对象中。属性。

当您访问虚拟属性时,Mongoose将检查属性类型并为该属性类型调用getter(基本上,调用您为虚拟属性定义的函数)。

答案 1 :(得分:1)

是的,data仅包含您在pick中列出的属性。如果您的req.body包含其他字段,则该字段不在data

对于最重要的部分,取决于你是如何做到的。在本机mongodb驱动程序中,API调用对于插入和更新是不同的。更新还可以区分覆盖整个条目(使用$set)或仅填写字段。但是在mongoose中,简单的顶级更新确实取代了整个文档。所以,如果你正在使用它并希望限制条目,是的。你可以阅读它here

但是,最好还是检查一下你要存储在数据库中的内容。 pick完全用于清除不需要的数据。