如何在Express.js,mongodb中注册时检查文档中的两个字段?

时间:2016-10-15 11:56:46

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

我为用户和注册时间设计了架构我正在检查已经存在或不存在的电子邮件(唯一)。如果已经注册我正在扔电子邮件地址已经在使用'。这工作正常现在我想检查两个字段的电子邮件和mobilenumber。我怎么能实现这个?帮助我

下面是我的完整用户架构设计

    'use strict';

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    var UserSchema = new Schema({
        name: String,
        mobilenumber : String,
        email: {
            type: String,

        },
        hashedPassword: String,
        provider: String,
        salt: String,
    });

    /**
     * Virtuals
     */
    UserSchema
      .virtual('password')
      .set(function(password) {
        this._password = password;
        this.salt = this.makeSalt();
        this.hashedPassword = this.encryptPassword(password);
      })
      .get(function() {
        return this._password;
      });

    // Public profile information
    UserSchema
      .virtual('profile')
      .get(function() {
        return {
          'name': this.name,
          'role': this.role
        };
      });

    // Non-sensitive info we'll be putting in the token
    UserSchema
      .virtual('token')
      .get(function() {
        return {
          '_id': this._id,
          'role': this.role
        };
      });

    /**
     * Validations
     */

    // Validate empty email
    UserSchema
      .path('email')
      .validate(function(email) {
        if (authTypes.indexOf(this.provider) !== -1) return true;
        return email.length;
      }, 'Email cannot be blank');

    // Validate empty password
    UserSchema
      .path('hashedPassword')
      .validate(function(hashedPassword) {
        if (authTypes.indexOf(this.provider) !== -1) return true;
        return hashedPassword.length;
      }, 'Password cannot be blank');

    // Validate email is not taken
    UserSchema
        .path('email')
        .validate(function(value, respond) {
            var self = this;
            this.constructor.findOne({
                email: value
            }, function(err, user) {
                if (err) throw err;
                if (user) {
                    if (self.id === user.id) return respond(true);
                    return respond(false);
                }
                respond(true);
            });
        }, 'email address is already in use.');

    var validatePresenceOf = function(value) {
        return value && value.length;
    };


/**
 * Pre-save hook
 */
UserSchema
  .pre('save', function(next) {
    if (!this.isNew) return next();

    if (!validatePresenceOf(this.hashedPassword) && authTypes.indexOf(this.provider) === -1)
      next(new Error('Invalid password'));
    else
      next();
  });

/**
 * Methods
 */
UserSchema.methods = {
  /**
   * Authenticate - check if the passwords are the same
   *
   * @param {String} plainText
   * @return {Boolean}
   * @api public
   */
  authenticate: function(plainText) {
    return this.encryptPassword(plainText) === this.hashedPassword;
  },

  /**
   * Make salt
   *
   * @return {String}
   * @api public
   */
  makeSalt: function() {
    return crypto.randomBytes(16).toString('base64');
  },

  /**
   * Encrypt password
   *
   * @param {String} password
   * @return {String}
   * @api public
   */
  encryptPassword: function(password) {
    if (!password || !this.salt) return '';
    var salt = new Buffer(this.salt, 'base64');
    return crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64');
  }
};

module.exports = mongoose.model('User', UserSchema);

在注册时间内,如果用户输入已经注册的电子邮件或移动电话号码,则应该抛出错误,例如电子邮件地址已被使用'或者' mobilenumber已经在使用' 。如果使用的话,电子邮件和手机号码都是匹配的或匹配的。帮助我?

2 个答案:

答案 0 :(得分:1)

您应该创建一种检查电子邮件和mobileNumber的方法,而不是验证字段。检查以下代码:

UserSchema.statics.validateMobileAndEmail= function (email, mobileNumber, cb) {
  return this.find({email: email, mobileNumber: mobileNumber}).exec(function(err, user){
    if(err) return cb(err);

    if(user.email === email && user.mobileNumber === mobileNumber){
       return cb(null, 'email and mobilenumber already exists');
    } else if(user.email === email ){
       return cb(null, 'email already exists');
    } else if(user.mobileNumber === mobileNumber){
       return cb(null, ' mobilenumber already exists');
    } 
    return cb();
 })
}

在创建记录之前,请使用电子邮件和mobileNumber调用它。

UserSchema.validateMobileAndEmail(email, mobileNumber, function(err, msg){
   if(err){ return res.json({error:'internal server error'});}
   else if(msg) {return res.json({error: msg});}
   else{
      // register user code
   }

})

离。

UserSchema.validateMobileAndEmail('email@email.com', '2222222222', function(err, msg){
       if(err){ return res.json({error:'internal server error'});}
       else if(msg) {return res.json({error: msg});}
       else{
          // register user code
       }

    })

答案 1 :(得分:0)

您可以在这两个字段上进行验证,但是mongoose会显示第一次验证失败的错误,它不会同时显示两个验证错误。

如果电子邮件和手机都存在,它会显示您的电子邮件地址已被使用。因为当第一次验证失败时猫鼬会停止。

如果您没关系,只需在电子邮件验证下为移动设备添加相同的验证。

UserSchema
    .path('mobilenumber')
    .validate(function(value, respond) {
        var self = this;
        this.constructor.findOne({
            mobilenumber : value
        }, function(err, user) {
            if (err) throw err;
            if (user) {
                if (self.id === user.id) return respond(true);
                return respond(false);
            }
            respond(true);
        });
    }, 'mobile is already in use.');

另外,您可以在代码中添加自定义验证。