0

我有一个问题,我不太确定为什么我不能解决我的问题。

我有一个使用 AngularJS、Node.JS 和 MongoDB (Mongoose) 构建的 SPA。现在在客户端我有一个表格来注册一个新用户。该表单有一个文本输入,该输入具有与其onblur事件相关联的功能(或者ng-blur准确地说)。Ajax/$http该函数在提交表单之前向后端发送调用以检查用户名是否唯一。一切正常,这是我到目前为止的代码(请注意,我已经稍微修改了这个问题的代码)......

这是文本框,

<input type="text" name="displayName" id="displayName" ng-model="user.displayName" ng-blur="checkUserName(user)" />

这是我控制器中的模糊功能

this.userNameCheck = function(user){
        return $http({method: 'GET', url: '/api/users/displayName/' + user.displayName})
            .then(function(response) {
               if(response.data.length > 0){
                   user.userWarning = userWarning; // userWarning is a string/ var that is passed to the form
               }

            }, function(response) {
                console.log(response);
            });
    };

这是我的节点/猫鼬代码,它包含在不同的项目中:

exports.displayName = function (req, res, next, displayName) {

    User.find({displayName : displayName}).limit(1).exec(function (err, results) {
        if (err) return next(err);
        if (!results) return next(new Error('No user found'));
        res.jsonp(results || null);
    });

};

这一切都很棒,但是当我在控制台中检查时,我可以看到当我们匹配时,返回的结果对象包含哈希密码、盐等所有内容......我想防止这些在我的对象中返回. 所以我修改了我的后端代码:

exports.displayName = function (req, res, next, displayName) {

    User.find({displayName : displayName}).limit(1).exec(function (err, results) {
        if (err) return next(err);
        if (!results) return next(new Error('No user found'));

        // new code
        if(results.length !== 0){
            var returnObj =  results[0];
             delete returnObj.hashed_password;
             delete returnObj.salt;
             delete returnObj._id;
            res.jsonp([returnObj] || null)
        }else{
            res.jsonp(results || null);
        }
    });

};

现在,当在 Firebug 中检查成功调用返回的内容(已找到匹配项)时,返回的对象仍然包含已删除的属性......我哪里出错了?

4

2 回答 2

3

您正在尝试从 Mongoose 对象中删除,而不是从实际存储中删除。最简单的改变是:

 var returnObj =  results[0].toJSON();
 delete returnObj.hashed_password;
 delete returnObj.salt;
 delete returnObj._id;

您也可以只select文档)要包含/排除的字段。

于 2013-10-02T12:16:30.707 回答
0

我的猜测是返回对象在原型链的上游具有这些属性,因此它们实际上并没有被删除。

如果删除操作符成功,它会从对象中完全删除该属性。但是,如果对象的原型链上存在同名的属性,则对象将从原型继承该属性。

〜MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

您可以检查这一点hasOwnProperty以测试该理论,但仅构建所需值的动态对象或限制从 Mongo 返回的值可能更安全?

换句话说,使用 JavaScript 即时(类似):

var returnObj =  results[0],
safeUserObj = {
   userName : returnObj["username"],
   email : returnObj["email"]
};

res.jsonp([safeUserObj]);

$match或者您可以使用聚合框架的and仅从 Mongo 返回您想要的字段$project。(下面的控制台样式代码,不确定您需要如何为 Mongoose 调整它)

db.users.aggregate([
{ $match : { displayName : displayName } },
{ $project : {
    displayName : 1,
    email : 1
  }
}
]);

编辑:提到您可以使用 find 的项目参数来做与我在底部解决方案中所做的相同的事情,而无需使用聚合框架。

于 2013-10-02T10:24:54.900 回答