如何保护MongoDB / MongoDB中的密码字段,以便在填充集合时不会在查询中返回?

假设我有两个集合/架构。 一个是带有用户名和密码字段的用户模式,然后,我有一个博客模式,在作者字段中引用了用户模式。 如果我使用mongoose做类似的事情

Blogs.findOne({...}).populate("user").exec() 

我将有博客文档和用户填充,但我如何防止Mongoose / MongoDB返回密码字段? 密码字段被哈希,但不应该返回。

我知道我可以省略密码字段,并在一个简单的查询中返回其余的字段,但我怎么做与填充。 另外,有没有优雅的方式来做到这一点?

此外,在某些情况下,我确实需要获取密码字段,例如当用户想要login或更改密码。

 .populate('user' , '-password') 

http://mongoosejs.com/docs/populate.html

JohnnyHKs使用Schema选项的答案可能是这里的方法。

还要注意query.exclude()只存在于2.x分支中。

您可以使用字段的select属性更改模式定义级别的默认行为:

 password: { type: String, select: false } 

然后,您可以根据需要将其拉入,并通过字段selectpopulate '+password' 。 例如:

 Users.findOne({_id: id}).select('+password').exec(...); 

编辑:

在尝试了两种方法后,我发现由于某种原因,使用护照本地策略的排除总是方法不适合我,不知道为什么。

所以,这就是我最终使用的:

 Blogs.findOne({_id: id}) .populate("user", "-password -someOtherField -AnotherField") .populate("comments.items.user") .exec(function(error, result) { if(error) handleError(error); callback(error, result); }); 

排除总是没有问题,因为某些原因,护照不起作用,我的testing告诉我,实际上密码被排除/包括在我想要的时候。 包含总是方法的唯一问题是,我基本上需要经历每一个我对数据库的调用,并排除了很多工作的密码。


经过一番精彩的回答,我发现有两种做法,“有时候总是包含和排除”和“总是排除包含有时”?

两者的一个例子:

总是包括但不包括有时的例子:

 Users.find().select("-password") 

要么

 Users.find().exclude("password") 

总是令人费解的例子包括

 Users.find().select("+password") 

但是您必须在模式中定义:

 password: { type: String, select: false } 

假设你的密码字段是“密码”,你可以做:

 .exclude('password') 

这里有一个更广泛的例子

这是集中在评论,但这是相同的原则在发挥。

这与在MongoDB的查询中使用投影并在投影字段中传递{"password" : 0} 。 看到这里

User.find().select('-password')是正确的答案。 您无法在模式上添加select: false ,因为如果您想要login,它将不起作用。

这是更多的原始问题的必然结果,但这是我遇到的问题,试图解决我的问题…

也就是说,如何在没有密码字段的user.save()callback中将用户发送回客户端。

用例:应用程序用户从客户端更新其个人资料信息/设置(密码,联系信息,whatevs)。 在成功保存到mongoDB后,您希望将更新后的用户信息发送回客户端。

 User.findById(userId, function (err, user) { // err handling user.propToUpdate = updateValue; user.save(function(err) { // err handling /** * convert the user document to a JavaScript object with the * mongoose Document's toObject() method, * then create a new object without the password property... * easiest way is lodash's _.omit function if you're using lodash */ var sanitizedUser = _.omit(user.toObject(), 'password'); return res.status(201).send(sanitizedUser); }); }); 

Blogs.findOne({ _id: id }, { "password": 0 }).populate("user").exec()