node.js - 如何检查具有电子邮件的用户是否已经存在?

标签 node.js mongodb express mongoose mongodb-query

我正在尝试阻止使用以前注册的电子邮件进行注册。我尝试在 Mongoose 模式中创建自定义验证。但它给了我一个错误ValidationError:用户验证失败 在 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');
    }

最佳答案

检查电子邮件 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

关于node.js - 如何检查具有电子邮件的用户是否已经存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42381683/

相关文章:

node.js - 在生产环境中使用 node.js

node.js - Nodejs 和 mongodb 刷新错误?

arrays - 更新深度嵌套数组 mongodb

node.js - express.js 套接字池

json - node.js 中的只读 JSON 对象

node.js - 将 onEnabled 方法与 QnAMakerRecognizer 结合使用

java - Containing 可以用在 Spring Data 中的列表上吗?

javascript - Mongoose 异步多次保存冲突

javascript - socket.io 函数在回调完成之前返回 - Node.js

javascript - Express (node.js) - res.send 仅发送部分响应