需要Mongoose.js上的几个列之一

时间:2014-11-05 19:44:36

标签: node.js mongodb express mongoose passport.js

在Mongoose.js的单个集合中,是否有任何方法只需要一个(或多个,但不是全部)几个列?在我的情况下,我使用Passport并希望我的用户通过我提供的提供商之一注册,或者自己创建。但是,我不想要求用户通过任何一个提供商进行注册,而是要求他/她所希望的那个。

以下是来自the scotch.io tutorial on Passport的示例架构(注意:这是一个示例。我不会在我的应用中使用它,但可能会使用类似的内容):< / p>

// app/models/user.js
// load the things we need
var mongoose = require('mongoose');
var bcrypt   = require('bcrypt-nodejs');

// define the schema for our user model
var userSchema = mongoose.Schema({

    local            : {
        email        : String,
        password     : String,
    },
    facebook         : {
        id           : String,
        token        : String,
        email        : String,
        name         : String
    },
    twitter          : {
        id           : String,
        token        : String,
        displayName  : String,
        username     : String
    },
    google           : {
        id           : String,
        token        : String,
        email        : String,
        name         : String
    }

});

// methods ======================
// generating a hash
userSchema.methods.generateHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

// checking if password is valid
userSchema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.local.password);
};

// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);

如何确保至少指定了localfacebooktwittergoogle中的一个对象(不是null,在保存文档之前没有undefined等,而不需要任何一个(并且不需要其他的)或者需要所有这些文件?就应用而言,这将要求用户首次通过用户名&amp;密码; Twitter或Facebook OAuth帐户或Google+ OpenID帐户。但是,用户不会被绑定到任何一个提供商,因此他/她不必通过用户名和用户进行注册。密码,但他/她也不必通过社交网络帐户注册,如果这不是他/她的事情。

1 个答案:

答案 0 :(得分:2)

我会尝试使用全局预验证挂钩:

const providers = ['google', 'twitter', 'facebook', 'local'];

userSchema.pre('validate', function(next) {
 let hasProvider = false;

 // not sure if this is needed, but sometimes, the scoping is messed up
 const that = this;

 // you should add more validations, e.g. for fields, too
 hasProvider = providers.some(provider => that.hasOwnProperty(provider));

 return (hasProvider) ? next() : next(new Error('No Provider provided'));
});

注意:仅当实际调用了预验证钩子时,此方法才有效。如果仅使用.save(),则根据docs可以没事。

  

save()函数触发validate()钩子,因为猫鼬有一个   内置的pre('save')钩子调用validate()。这意味着所有   pre('validate')和post('validate')挂钩在任何之前被调用   pre('save')钩子。

如果您使用绕过验证的函数,则可能会导致问题。检查https://mongoosejs.com/docs/validation.html了解更多信息!