2017-10-17 2 views
0

J'écris une API en utilisant Express, MongoDB et Mongoose. Je suis en quelque sorte en mesure de créer plusieurs utilisateurs avec le même e-mail. Cependant, je ne devrais pas être en mesure de créer un autre utilisateur avec la même adresse e-mail. J'ai l'email unique: true dans mon schéma d'utilisateur, mais ceci ne fonctionne pas comme prévu.Capable de créer plusieurs utilisateurs avec le même e-mail, même si le courrier électronique est unique dans Mongoose

Voici mon schéma utilisateur:

var UserSchema = new Schema({ 
fullName: { type: String, required: [true, 'Full name is required.'] }, 
emailAddress: { 
    type: String, required: true, unique: true, 
    validate: { 
     validator: function (value) { 
      // check for correct email format 
      return /^[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-][email protected][a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(value) 
     }, 
     message: `Please enter a valid email address!` 
    } 
}, 
password: { type: String, required: true } 
}); 

Ma méthode authenticate utilisateur:

UserSchema.statics.authenticate = function (email, password, callback) { 
User.findOne({ emailAddress: email }) 
    .exec(function (err, user) { 
     if (err) { 
      return callback(err); 
     } else if (!user) { 
      var error = new Error('User not found'); 
      error.status = 401; 
      return callback(error); 
     } 
     bcrypt.compare(password, user.password, function (error, user) { 
      if (user) { 
       return callback(null, user); 
      } else { 
       return callback(); 
      } 
     }); 
    }); 
} 

Mon crochet de pré-enregistrement de hachage du mot de passe:

UserSchema.pre('save', function (next) { 
var user = this; 
bcrypt.hash(user.password, 10, function (err, hash) { 
    if (err) { 
     return next(err); 
    } 
    user.password = hash; 
    next(); 
}); 
}); 

Et enfin, mon utilisateur créer un itinéraire:

router.post('/', function (req, res, next) { 
if (req.body.fullName && 
    req.body.emailAddress && 
    req.body.password && 
    req.body.confirmPassword) { 

    if (req.body.password != req.body.confirmPassword) { 
     var err = new Error('Passwords do not match!'); 
     err.status = 400; 
     return next(err); 
    } 

    // object with form input 
    var userData = { 
     fullName: req.body.fullName, 
     emailAddress: req.body.emailAddress, 
     password: req.body.password 
    }; 

    // schema's 'create' method to insert document into Mongo 
    User.create(userData, function (error, user) { 
     if (error) { 
      var err = new Error('Please enter a valid email.'); 
      err.status = 400; 
      return next(err); 
     } else { 
      // set location header to '/', return no content 
      res.status(201); 
      res.location('/'); 
      req.session.userId = user._id; 
      return res.json(user); 
     } 
    }); 

} else { 
    var err = new Error('All fields required.'); 
    err.status = 400; 
    return next(err); 
} 
}); 
+0

Votre document utilisateur a-t-il un champ '_id' avec un' ObjectId' assigné? – wscourge

+0

@wscourge Oui, ce qui suit est ce qui est retourné, avec '_id' généré automatiquement (je ne suis pas sûr de ce que vous entendez par' ObjectId', mais je crois que la valeur du champ '_id' est ce que vous cherchez '' '{ "__v": 0, "fullName": "John Smith", "emailAddress": "[email protected]", "mot de passe": « $ 2a $ 10 $ P.VQVungzx9wMyKrI7nOu.1Sh5ikfB1SYUpzi /hFqqu.Ae4wM4c2. ", " _id ":" 59e657e08d643599fe1de35a " }' '' – wellowlbe

+1

Si vous êtes dans un environnement de test, vous pouvez essayer d'arrêter l'application, en insérant 'mongoose.set ('debug', true)' right après l'instruction de connexion mongoose (pour le débogage détaillé), en fermant mongod puis en redémarrant mongod et votre application Vous pourriez avoir ce problème parce que l'index n'a pas été créé après réglage unique à vrai. Voir [ici] (http://mongoosejs.com/docs/guide.html#indexes) pour plus d'informations. Redémarrer l'application devrait créer l'index et unique pourrait fonctionner après cela. – MikaS

Répondre

1

MongoDB ne crée pas d'index unique à un champ si la valeur du champ contient déjà des doublons.

Dans votre cas, emailAddress doit avoir des doublons déjà stockés dans la base de données. Vous pouvez le vérifier en runing le code

mongoose .model(#modelName) .collection.createIndex({ "inviteCode": 1 });

Après avoir exécuté ce code, vous devriez être en mesure de voir un message d'erreur dans la console.

Ou Vous pouvez vérifier en exécutant le code ci-dessous si vous avez des doublons. Ci-dessous va chercher des documents si ont des doublons:

mongoose .model(#modelName).aggregate([{ "$group": { "_id": "$loginStatus", count: { $sum: 1 }, ids: { $push: "$_id" } } },{ $match: { count: { $gt : 1 } }}]);

Si vous envoyez un email qui est déjà en double, vous ne pouvez pas créer un seul: true. Vous devrez exécuter la deuxième requête et trouver l'adresse e-mail en double. Vous pouvez trouver les documents avec un courrier électronique en double dans le tableau ids.