如何检查用户是否已经存在电子邮件?

时间:2017-02-22 02:35:18

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

我正在尝试使用之前注册的电子邮件阻止注册。我试图在mongoose架构中创建自定义验证。但它给了我一个错误 ValidationError:用户验证失败     在MongooseError.ValidationError 。代码下降了。有人可以告诉我错误在哪里或更好的方法来检查db中是否存在用户电子邮件。

// 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');
    }

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

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

中进行验证
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可以保留而无需任何验证。

答案 2 :(得分:1)

您可以使用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})
        }
    })
})