8

Ok so I have a JS object that is being POSTed via AJAX to the nodejs backend. I want to insert this js object directly into my mongoose db as the object keys already match up perfectly with the db schema.

I currently have this (not dynamic and overly complex):

app.post('/items/submit/new-item', function(req, res){
    var formContents = req.body.formContents,
        itemModel = db.model('item'),
        newitem = new itemModel();

    newitem.item_ID         = "";
    newitem.item_title      = formContents.item_title;
    newitem.item_abv        = formContents.item_abv;
    newitem.item_desc       = formContents.item_desc;
    newitem.item_est        = formContents.item_est;
    newitem.item_origin     = formContents.item_origin;
    newitem.item_rating     = formContents.item_rating;
    newitem.item_dateAdded  = Date.now();

    newitem.save(function(err){
        if(err){ throw err; }
        console.log('saved');
    })

    res.send('item saved');
});

But want to trim it down to something like this (sexy and dynamic):

app.post('/items/submit/new-item', function(req, res){
    var formContents = req.body.formContents,

    formContents.save(function(err){
        if(err){ throw err; }
        console.log('saved');
    })

    res.send('item saved');
});
3
  • 2
    "Ok so I have a JS object that is being POSTed via AJAX to the nodejs backend. I want to insert this js object directly into my mongoose db as the object keys already match up perfectly with the db schema." Sounds like an excellent vector for some kind of injection attack, similar to SQL injection. Always better to process and validate your data on the server before sending it. Clients cannot be trusted. Commented Sep 23, 2011 at 9:10
  • 2
    Yes I know. This is a test case. That was not my question. Commented Sep 23, 2011 at 9:12
  • So it's a bad test case, as you should ALWAYS validate data :) I'm currently working in a similar context and successfully tested validate.js to validate the data Commented Apr 30, 2014 at 10:06

1 Answer 1

9

If you use a plugin like this with mongoose (http://tomblobaum.tumblr.com/post/10551728245/filter-strict-schema-plugin-for-mongoose-js) you can just put together an array in your form, like newitem[item_title] and newitem[item_abv] -- or item[title] and item[abv]

You could also just pass the whole req.body if the elements match up there. That MongooseStrict plugin will filter out any values not explicitly set in your schema, but it still leaves checking types and validation up to mongoose. With proper validation methods set in your schema, you will be safe from any injection attacks.

EDIT: Assuming you have implemented the plugin, you should be able to use this code.

app.post('/items/submit/new-item', function(req, res){
  new itemModel(req.body.formContents).save(function (e) {
    res.send('item saved');
  });
});
Sign up to request clarification or add additional context in comments.

9 Comments

thanks the method you described worked without requiring the plugin. I will definately need to implement it at a further date to ensure security though. What is the point in schemas if they can be overridden like this? What other methods of input validation would you suggest?
Schemas do a lot in mongoose, most importantly they save types properly into mongodb but they also let you setup validation, defaults, and other ODM stuff. At the moment the top level of a mongoose doc is essentially treated like the type "Mixed" (which accepts anything and only does stuff when the property updated matches a property in the schema) -- the plugin forces mongoose to only accept properties in the schema
Coming from a mySQL background I am struggling to understand mongoose fully. The docs are not that clear to me. Could you recommend some resources or examples. I'm not looking to do anything advanced.
The google group is a good place to start, and you can usually find help on irc pretty quickly in #node.js on freenode.net
@NikMartin schemas are strict by default now
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.