using _.omit on mongoose User in node.js

2019-07-03 22:51发布

问题:

I have a mongoose User schema built like this:

var UserSchema = new Schema({
    username: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true },
    salt: { type: String, required: true}
});

I want to be able to send this user object to the client side of my application but I don't want to sned the password or salt fields.

So I added he following code to my user model module

U

serSchema.methods.forClientSide = function() {
    console.log('in UserSchema.methods.forClientSide');
    console.log(this);
    //var userForClientSide=_.omit(this,'passsword','salt');
    var userForClientSide={_id:this._id, username:this.username };
    console.log(userForClientSide);

    return userForClientSide;
}

I have required the underscore module (its installed locally via a dependency in my package.js).

not the commented out line - I was expecting it to omit the password and salt fields of the user object but it did not do anything :( the logged object had the full set of properties.

when replaced with the currently used like var userForClientSide={_id:this._id, username:this.username }; it gets the results I want but:

1) I want to know why does the _.omit not work. 2) I don't like my current workaround very much because it actually selects some properties instead of omitting the ones I don't like so if I will add any new propertes to the scema I will have to add them here as well.

This is my first attempt at writing something using node.js/express/mongodb/mongoose etc. so It is very possible hat I am missing some other better solution to this issue (possibly some feature of mongoose ) feel free to educate me of the right way to do things like this.

so basically I want to know both what is the right way to do this and why did my way not work.

thanks

回答1:

1) I want to know why does the _.omit not work.

Mongoose uses defineProperty and some heavy metaprogramming. If you want to use underscore, first call user.toJSON() to get a plain old javascript object that will work better with underscore without all the metaprogramming fanciness, functions, etc.

A better solution is to use mongo/mongoose's fields object and pass the string "-password -salt" and therefore just omit getting these back from mongo at all.

Another approach is to use the mongoose Transform (search for "tranform" on that page). Your use case is the EXACT use case the documentation uses as an example.

You can also make your mongoose queries "lean" by calling .lean() on your query, in which case you will get back plain javascript objects instead of mongoose model instances.

However, after trying each of these things, I'm personally coming to the opinion that there should be a separate collection for Account that has the login details and a User collection, which will make leaking the hashes extremely unlikely even by accident, but any of the above will work.