【问题标题】:Require One of Several Columns on Mongoose.js需要 Mongoose.js 上的几个列之一
【发布时间】:2015-01-02 03:33:20
【问题描述】:

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

这是来自the scotch.io tutorial on Passport 的示例架构(注意:这是一个示例。我不会在我的应用程序中使用它,但可能会使用类似的东西):

// 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 等)文件,而不需要任何一个(和其他不需要的)或全部都需要?就应用而言,这将要求用户首次通过用户名和密码进行注册; Twitter 或 Facebook OAuth 帐户,或 Google+ OpenID 帐户。但是,用户不会与任何一个提供商绑定,因此他/她不必通过用户名和密码进行注册,但如果不是他/她,他/她也不必通过社交网络帐户进行注册东西。

【问题讨论】:

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


【解决方案1】:

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

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() 钩子,因为 mongoose 有一个 调用 validate() 的内置 pre('save') 钩子。这意味着所有 pre('validate') 和 post('validate') 钩子在任何之前被调用 pre('save') 钩子。

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

【讨论】:

    猜你喜欢
    • 2019-09-07
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 2022-10-15
    相关资源
    最近更新 更多