Санитарная обработка данных перед сохранением в Mongoose

Я пытаюсь создать предварительный обработчик, который очищает все данные перед их записью в MongoDB, см. http://mongoosejs.com/docs/middleware.html

Я пробовал следующее, чтобы каждое свойство могло его дезинфицировать:

  blogSchema.pre('save', function (next) {
        var obj = this;
        console.log(obj)//-> https://gist.github.com/daslicht/70e0501acd6c345df8c2

        // I've tried the following to get the single items :
        Object.keys(obj).forEach(function (key) {
            console.log('Keys: ',obj[key]);
        });

        //and:
        for(var key in obj) {
            console.log(obj[key])
        }

        //and:
        _.each( self , function(value, key, list){
            console.log('VALUE:',key);
       })
        next();
    })

Любой из вышеперечисленных подходов приводит к чему-то вроде следующего:

Вот результат:

    for(var key in obj) {
       console.log(obj[key])
    }

https://gist.github.com/daslicht/cb855f53d86062570a96

Кто-нибудь знает, как получить каждое свойство, чтобы я мог его дезинфицировать, пожалуйста?

~ Марк

[РЕДАКТИРОВАТЬ] Вот один из возможных обходных путей, в любом случае было бы лучше иметь его непосредственно на уровне схемы, так как это было бы более сухим

        var post = {
            createdAt : req.body.date,
            createdBy : req.user.username,
            headline : req.body.headline,
            content : req.body.content
        }

        _.each( post , function(value, key, list){
           post[key] =  sanitize(value).xss(); //its the sanetize function of node validator
        })

        var item = new Blog(post);

4 ответа

Вы можете использовать плагин mongoose-sanitizer, который использует Google Caja для выполнения очистки.

Наверное, не лучший способ сделать это.

Мангуст имеет полевые валидаторы

Стандартных валидаторов обычно достаточно, чтобы выполнить работу, но пользовательские валидаторы легко создать, как указано в документации.

Пример пользовательского валидатора из документов

var Toy = mongoose.model('Toy', toySchema);

Toy.schema.path('color').validate(function (value) {
  return /blue|green|white|red|orange|periwinkle/i.test(value);
}, 'Invalid color');

Согласно этой теме, я думаю, что вы можете сделать

blogSchema.pre('save', function (next) {
    var obj = this;
    blogSchema.schema.eachPath(function(path) {
        SanitizeAndThrowErrorIfNecessary(obj(path), next);
    }); 
    //Validation and Sanitization passed
    next();
})

Даже если вы можете установить это успешно, обратите внимание, что Model.update не будет вызывать хук предварительного сохранения. Проверьте эту проблему GitHub

Вот простой способ сделать это. При этом используется async.js, но вы можете изменить его для использования универсального цикла JS или любой другой библиотеки потоков управления. Ключ заключается в том, чтобы получить массив полей документа, затем вы можете перебрать их и получить / установить значения, используя текущий контекст с this, Насколько я знаю, это не приведет к нестроковым значениям в строки. Я протестировал его со строками, числами, логическими значениями и объектными идентификаторами, и они успешно сохраняются в качестве исходных типов данных.

yourSchema.pre('save', function (next) {
  var self = this;

  // Get the document's fields
  var fields = Object.keys(this._doc);

  // Iteratively sanitize each field
  async.each(fields, function(field, cb) {
    self[field] = validator.escape(self[field]);
    cb();
  }, function(err){
    next();
  });
});
Другие вопросы по тегам