117 votes

Comment protéger le champ du mot de passe dans Mongoose/MongoDB pour qu'il n'apparaisse pas dans une requête lorsque je remplis des collections ?

Supposons que j'ai deux collections/schémas. L'un est le schéma Users avec des champs nom d'utilisateur et mot de passe, puis j'ai un schéma Blogs qui a une référence au schéma Users dans le champ auteur. Si j'utilise Mongoose pour faire quelque chose comme

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

Le document Blog et l'utilisateur seront également remplis, mais comment empêcher Mongoose/MongoDB de renvoyer le champ du mot de passe ? Le champ du mot de passe est haché mais il ne devrait pas être renvoyé.

Je sais que je peux omettre le champ du mot de passe et renvoyer le reste des champs dans une simple requête, mais comment puis-je faire cela avec populate. Existe-t-il un moyen élégant de le faire ?

De plus, dans certaines situations, j'ai besoin d'obtenir le champ du mot de passe, par exemple lorsque l'utilisateur veut se connecter ou modifier son mot de passe.

385voto

JohnnyHK Points 61191

Vous pouvez modifier le comportement par défaut au niveau de la définition du schéma à l'aide de la commande select du champ :

password: { type: String, select: false }

Ensuite, vous pouvez le retirer selon les besoins dans find y populate via la sélection de champs comme '+password' . Par exemple :

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

77voto

aaronheckmann Points 3875
.populate('user' , '-password')

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

La réponse de JohnnyHKs utilisant les options de schéma est probablement la meilleure solution.

Notez également que query.exclude() n'existe que dans la branche 2.x.

39voto

Luis Elizondo Points 162

Edit :

Après avoir essayé les deux approches, j'ai constaté que l'approche consistant à exclure toujours ne fonctionnait pas pour moi, pour une raison quelconque, en utilisant la stratégie passeport-local, je ne sais pas vraiment pourquoi.

C'est donc ce que j'ai fini par utiliser :

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

Il n'y a rien de mal avec l'approche "exclure toujours", elle n'a simplement pas fonctionné avec le passeport pour une raison quelconque, mes tests m'ont montré qu'en fait le mot de passe était exclu / inclus quand je le voulais. Le seul problème avec l'approche "include always" est que je dois passer en revue tous les appels que je fais à la base de données et exclure le mot de passe, ce qui représente beaucoup de travail.


Après quelques bonnes réponses, j'ai découvert qu'il y a deux façons de faire, la "toujours inclure et exclure parfois" et la "toujours exclure et inclure parfois" ?

Un exemple des deux :

L'inclure toujours mais l'exclure parfois exemple :

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

o

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

L'exclure toujours mais l'inclure parfois exemple :

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

mais vous devez le définir dans le schéma :

password: { type: String, select: false }

19voto

Ikbel Points 3219

Vous pouvez y parvenir en utilisant le schéma, par exemple :

const UserSchema = new Schema({/* */})

UserSchema.set('toJSON', {
    transform: function(doc, ret, opt) {
        delete ret['password']
        return ret
    }
})

const User = mongoose.model('User', UserSchema)
User.findOne() // This should return an object excluding the password field

14voto

Ylli Gashi Points 615

User.find().select('-password') est la bonne réponse. Vous ne pouvez pas ajouter select: false sur le schéma car il ne fonctionnera pas, si vous voulez vous connecter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X