2012-08-23 11 views
45

Supponiamo che abbia due collezioni/schemi. Uno è lo schema degli utenti con campi nome utente e password, quindi, ho uno schema Blog che ha un riferimento allo schema utenti nel campo autore. Se uso Mangusta fare qualcosa di simileCome proteggere il campo password in Mongoose/MongoDB in modo che non ritorni in una query quando popolo le raccolte?

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

avrò il documento Blog e l'utente popolata troppo, ma come faccio a prevenire Mongoose/MongoDB di tornare il campo della password? Il campo della password è sottoposto a hash ma non dovrebbe essere restituito.

So che posso omettere il campo della password e restituire il resto dei campi in una query semplice, ma come faccio a farlo con popola. Inoltre, c'è un modo elegante per farlo?

Inoltre, in alcune situazioni ho bisogno di ottenere il campo della password, come quando l'utente vuole accedere o modificare la password.

+0

si può anche fare .popolare ('utente': 1, 'password': 0) –

risposta

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

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

JohnnyHKs rispondere utilizzando le opzioni dello schema è probabilmente il modo di andare qui.

Si noti inoltre che query.exclude() esiste solo nel ramo 2.x.

+0

funziona anche .populate ('user': 1, 'password': 0) –

3

Assumendo che il campo password è "password" si può solo fare:

.exclude('password') 

C'è un più ampio esempio here

che si concentra sui commenti, ma è lo stesso principio in gioco.

È come utilizzare una proiezione nella query in MongoDB e passare {"password" : 0} nel campo di proiezione. Vedi here

+0

Grande. Grazie. Mi piace questo approccio. –

158

È possibile modificare il comportamento predefinito a livello di definizione dello schema utilizzando l'attributo select del campo:

password: { type: String, select: false } 

Poi si può tirare in base alle esigenze in find e populate chiamate tramite selezione campo come '+password' . Per esempio:

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

Grande. Puoi fornire un esempio su chi aggiungerlo alla ricerca? Supponendo che ho: Users.find ({id: _id}) dove dovrei aggiungere "+ password +? –

+0

Trovato l'esempio al link che hai fornito. Http://mongoosejs.com/docs/api.html#schematype_SchemaType-select Grazie –

+4

C'è un modo per applicare questo all'oggetto passato a save() callback? Tale che quando salvi un profilo utente la password non è inclusa nel parametro di callback. – Matt

11

Edit:

Dopo aver provato entrambi gli approcci, ho trovato che l'approccio escludere sempre non funzionava per me per qualche ragione con la strategia di passaporto locale, in realtà non so perché.

Quindi, questo è quello che ho finito per usare:

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

c'è niente di sbagliato con l'approccio escludere sempre, semplicemente non ha funzionato con il passaporto, per qualche ragione, i miei test mi hanno detto che in realtà la la password veniva esclusa/inclusa quando volevo. L'unico problema con l'approccio include include è che fondamentalmente ho bisogno di passare attraverso ogni chiamata che faccio al database ed escludere la password che è un sacco di lavoro.


Dopo un paio di grandi risposte ho scoperto ci sono due modi per farlo, il "includono sempre e esclude qualche volta" e il "sempre escludere e includere qualche volta"?

Un esempio di entrambi:

L'includono sempre ma esclude volte esempio:

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

o

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

L'exlucde sempre ma includono talvolta esempio:

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

ma è necessario definire nello schema:

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

Vorrei andare per l'ultima opzione .Non selezionare la password, tranne nel logIn/passwordUpdate funzioni davvero necessarie. – rdrey

+0

Per qualche motivo questa opzione non ha funzionato con la strategia locale Passport.js, non so perché: –

+0

Buona risposta, grazie !!! Non so perché, ma quando do '.select (" + field ")' porta solo '__id', anche se' .select ("- field") 'esclude piacevolmente il campo che voglio – renatoargh

0

questo è più un corollario alla domanda iniziale, ma questa è stata la domanda che mi sono imbattuto cercando di risolvere il mio problema ...

Vale a dire, come inviare l'utente al client nell'utente. save() callback senza campo password.

Caso di utilizzo: l'utente dell'applicazione aggiorna le informazioni/le impostazioni del profilo dal client (password, informazioni di contatto, whatevs). Si desidera inviare le informazioni utente aggiornate al client nella risposta, una volta che è stato salvato correttamente in 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') è la risposta giusta. Non è possibile aggiungere select: false allo schema poiché non funzionerà, se si desidera effettuare il login.

Problemi correlati