如何检查具有电子邮件的用户是不是已经存在?

Posted

技术标签:

【中文标题】如何检查具有电子邮件的用户是不是已经存在?【英文标题】: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');
    

【问题讨论】:

保存功能在哪里? 我昨天回答了一个类似的问题。看一看:***.com/questions/42362970/… 【参考方案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 无需任何验证即可保留。

【讨论】:

以上是关于如何检查具有电子邮件的用户是不是已经存在?的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHP 检查用户名和电子邮件是不是已经存在 [重复]

如何检查电子邮件是不是确实存在

如何远程验证电子邮件或检查电子邮件是不是存在

jQuery Validate Remote - 检查电子邮件是不是已经存在

CodeIgniter:检查记录是不是存在

检查数据库中是不是已存在电子邮件地址