【问题标题】:How to check if user with email already exists?如何检查具有电子邮件的用户是否已经存在?
【发布时间】:2017-07-11 22:09:51
【问题描述】:

我试图阻止使用以前注册的电子邮件进行注册。我试图在猫鼬模式中创建自定义验证。但它给了我一个错误 ValidationError: User validation failed 在 MongooseError.ValidationError。代码在下面。有人可以告诉我错误在哪里,或者是一种更好的方法来检查用户电子邮件是否存在于数据库中。

// user schema 
var UserSchema = mongoose.Schema({
    username: {
        type: String,
        index: true,
        require: true
    },
    password: {
        type: String,
        require: true
    },
    email: {
        type: String,
        lowercase: true,
        trim: true,
        index: {
            unique: true,
        },
        validate: {
            validator : isEmailExists, msg: 'Email already exists'
        }
    },
    name: {
        type: String
    },
    admin: Boolean,
    active: Boolean,
});

// validation
function isEmailExists(email, callback) {
    if (email) {
        mongoose.models['User'].count({ _id: { '$ne': this._id }, email: email }, function (err, result) {
            if (err) {
                return callback(err);
            }
            callback(!result);
        })
    }
}
// createUser function
module.exports.createUser = function(newUser, callback){
    bcrypt.genSalt(10, function(err, salt) {
        bcrypt.hash(newUser.password, salt, function(err, hash) {
            newUser.password = hash;
            newUser.save(callback);
        });
    });
}

路由器

router.post('/register', function(req, res, next) {
    var name = req.body.name;
    var email = req.body.email;
    var password = req.body.password;
    var confirmedPassword = req.body.confirmedPassword;

    // Validation
    req.checkBody('name', 'Name is required').notEmpty();
    req.checkBody('email', 'Email is required').notEmpty();
    req.checkBody('email', 'Email is not valid').isEmail();
    req.checkBody('password', 'Password is required').notEmpty();
    req.checkBody('confirmedPassword', 'Passwords do not match').equals(req.body.password);

    var errors = req.validationErrors();

    if (errors) {
        res.render('register', {
            errors: errors
        });
    } else {
        var newUser = new User({
            name: name,
            email: email,
            password: password,
            admin: false,
            active: false
        });

        User.createUser(newUser, function (err, user) {
            if (err) {
                throw err;
            }
        });

        req.flash('success_msg', 'You are registerd and can now login');
        res.redirect('/users/login');
    }

【问题讨论】:

标签: node.js mongodb express mongoose mongodb-query


【解决方案1】:

检查电子邮件 ID 是否已存在于数据库中的最佳方法是使用 express-validator。 自从升级到第 4 版后,API 发生了变化。 现在,而不是使用:-

const expressValidator = require('express-validator');

..在你的 app.js 文件中,然后调用中间件。相反,只需在您的用户路由文件中执行此操作:-

const { check, validationResult } = require('express-validator/check');

现在,要检查数据库中是否已经存在电子邮件 ID,您必须使用 Promise。这是一个工作代码:-

      router.post('/register', [
          check('name')
          .not()
          .isEmpty()
          .withMessage('Name is required'),
          check('email')
          .not()
          .isEmpty()
          .withMessage('Email is required')
          .isEmail()
          .withMessage('Invalid Email')
          .custom((value, {req}) => {
            return new Promise((resolve, reject) => {
              User.findOne({email:req.body.email}, function(err, user){
                if(err) {
                  reject(new Error('Server Error'))
                }
                if(Boolean(user)) {
                  reject(new Error('E-mail already in use'))
                }
                resolve(true)
              });
            });
          }),
          // Check Password
          check('password')
          .not()
          .isEmpty()
          .withMessage('Password is required'),
          // Check Password Confirmation
          check('confirmedPassword', 'Passwords do not match')
          .exists()
          .custom((value, { req }) => value === req.body.password)
        ], function(req, res) {
          var name = req.body.name;
          var email = req.body.email;
          var password = req.body.password;
          var confirmedPassword = req.body.confirmedPassword;

          // Check for Errors
          const validationErrors = validationResult(req);
          let errors = [];
          if(!validationErrors.isEmpty()) {
            Object.keys(validationErrors.mapped()).forEach(field => {
              errors.push(validationErrors.mapped()[field]['msg']);
            });
          }

          if(errors.length){
            res.render('register',{
              errors:errors
            });
          }  else {
            var newUser = new User({
              name: name,
              email: email,
              password: password,
              admin: false,
              active: false
            });

            User.createUser(newUser, function (err, user) {
              if (err) {
                throw err;
              }
            });

            req.flash('success_msg', 'You are registerd and can now login');
            res.redirect('/users/login');
          }

您也可以类似地执行此操作来检查用户名。 Here is the link to the official GitHub page of express-validator

【讨论】:

    【解决方案2】:

    你可以使用 Monsgoose 的 Model.findOne()=> https://mongoosejs.com/docs/api.html#model_Model.findOne:

    router.post('/register',(req,res)=>{
        // Object destructuring
        const {username,password,email,...rest} =req.body;
        // Error's Array
        let errors = [];
        // Mongoose Model.findOne()
        User.findOne({email:email}).then(user=>{
            if(user){
                errors.push({msg: 'Email already exists'});
                res.render('register',{errors})
            }
        })
    })
    

    【讨论】:

      【解决方案3】:

      您可以使用email-check 包检查用户之前是否注册过(email 字段中是否有重复的电子邮件地址)。
      这是下载包的链接 https://www.npmjs.com/package/email-check

      通过在Models 中写入unique: true 属性将提供不重复的邮件地址。但是您还应该包括 email-chack 验证,您可以在 Router

      中进行验证
      import emailCheck from "email-check";
      //other imports
      
      router.post("/register", (req, res) => {
          var name = req.body.name;
          var email = req.body.email;
          var password = req.body.password;
          var confirmedPassword = req.body.confirmedPassword;
      
          // your validation for another fields
          emailCheck(email)
              .then(() => {
                  User.create(req.body)
                      .then(() => {
                          res.send(req.body);
                      })
                      .catch((error) =>
                          res.json({serverErrorDublicateEmail: "The email address is already subscribed. Please try to use another one or simply Log in"});
                      });
              })
              .catch(() => {
                  res.json({serverErrorEmailExistence: "The email address doesn't exist. Please try the valid one"});
              });
      });
      

      emailCheck 返回一个承诺。注意:我使用的是 ES6 语法。

      就这样。您的UserSchema 无需任何验证即可保留。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-28
        • 1970-01-01
        • 2011-12-02
        • 1970-01-01
        • 2015-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多