如何保护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()