2012-08-23 11 views
45

假設我有兩個集合/模式。一個是帶有用戶名和密碼字段的用戶模式,然後,我有一個博客模式,該模式引用了作者字段中的用戶模式。如果我用貓鼬像做如何保護Mongoose/MongoDB中的密碼字段,使其在填充集合時不會在查詢中返回?

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

我將有博客的文件和填充過的用戶,但如何防止貓鼬/ MongoDB的從返回密碼字段?密碼字段已散列,但不應返回。

我知道我可以忽略密碼字段並在簡單的查詢中返回剩餘的字段,但是如何通過填充來完成。另外,有沒有優雅的方式來做到這一點?

此外,在某些情況下,我確實需要獲取密碼字段,例如用戶想要登錄或更改密碼時。

+0

你也可以做.populate( '用戶':1, '密碼':0) –

回答

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

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

JohnnyHKs回答使用模式的選擇可能是去這裏的路。

還要注意的是query.exclude()只有在2.x的分支存在。

+0

這也將工作.populate( '用戶':1, '密碼':0) –

3

假設你的密碼字段是「密碼」,你可以這樣做:

.exclude('password') 

還有一個更廣泛的例子here

,重點是評論,但它是在玩同樣的原則。

這與在MongoDB的查詢中使用投影並在投影字段中傳遞{"password" : 0}相同。見here

+0

大。謝謝。我喜歡這種方法。 –

158

可以使用該領域的select屬性的架構定義級別更改默認行爲:

password: { type: String, select: false } 

然後你就可以把它作爲通過現場選擇需要findpopulate電話爲'+password' 。例如:

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

太好了。你能提供一個例子來說明誰在find中添加它嗎?假設我有:Users.find({ID:_id})?我應該在哪裏添加「+密碼+ –

+0

找到你所提供的鏈接的例子http://mongoosejs.com/docs/api.html#schematype_SchemaType-select謝謝 –

+4

有沒有辦法將這個應用傳遞給save()回調的對象?這樣,當我保存一個用戶配置文件的時候,密碼不包含在回調參數中 – Matt

11

編輯:

嘗試這兩種方法後,我發現,一律排除方法是行不通的,我使用的護照本地策略某些原因,真的不知道是什麼原因。

所以,這就是我最終使用:

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

沒有什麼錯的排除總是方法,它只是沒有帶護照,出於某種原因,我的測試告訴我,其實當我想要時,密碼被排除/包括在內。包含總是方法的唯一問題是我基本上需要經歷每次對數據庫的調用,並排除很多工作的密碼。


後一對夫婦的偉大的答案,我發現有這樣做,「總是有,有時排除」的兩種方式和「永遠排除,有時包括」?

兩者的一個例子:

的包括總是但排除有時例如:

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

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

的總是exlucde但有時包括例如:

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

,但你必須在模式定義:

password: { type: String, select: false } 
+0

我會選擇最後一個選項,除非在logIn/passwordUpdate中選擇密碼,否則不要選擇密碼。功能你真的需要它。 – rdrey

+0

出於某種原因,選擇不與Passport.js當地的戰略合作,不知道爲什麼。 –

+0

很好的回答,謝謝!不知道爲什麼,但是當我儘管'.select(「 - field」)'很好地排除了我想要的字段 – renatoargh

0

這更是一個必然結果原來的問題,但是這是我碰到試圖解決我的問題就來了問題...

即如何給用戶發送回在用戶客戶端。保存()回調沒有密碼字段。

使用案例:應用程序用戶從客戶端更新他們的個人資料信息/設置(密碼,聯繫信息,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); 
    }); 
}); 
0

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

3

User.find().select('-password')是正確的答案。如果您想登錄,則無法在架構上添加select: false,因爲它不起作用。

相關問題