101

2 つのコレクション/スキーマがあるとします。1 つは、ユーザー名とパスワードのフィールドを持つユーザー スキーマです。次に、作成者フィールドにユーザー スキーマへの参照を持つブログ スキーマがあります。Mongoose を使用して次のようなことを行う場合

Blogs.findOne({...}).populate("user").exec()

ブログ ドキュメントとユーザーも入力しますが、Mongoose/MongoDB がパスワード フィールドを返さないようにするにはどうすればよいですか? パスワード フィールドはハッシュされますが、返されるべきではありません。

パスワード フィールドを省略して残りのフィールドを単純なクエリで返すことができることはわかっていますが、populate でそれを行うにはどうすればよいでしょうか。また、これを行うためのエレガントな方法はありますか?

また、ユーザーがログインしたりパスワードを変更したりする場合など、状況によってはパスワード フィールドを取得する必要があります。

4

15 に答える 15

345

selectフィールドの属性を使用して、スキーマ定義レベルでデフォルトの動作を変更できます。

password: { type: String, select: false }

次に、必要に応じてそれを取り込みfindpopulateフィールド選択を介して として呼び出すことができます'+password'。例えば:

Users.findOne({_id: id}).select('+password').exec(...);
于 2012-08-23T17:17:27.410 に答える
73
.populate('user' , '-password')

http://mongoosejs.com/docs/populate.html

スキーマオプションを使用したJohnnyHKの回答は、おそらくここに行く方法です。

query.exclude()また、2.x ブランチにのみ存在することにも注意してください。

于 2012-08-23T22:21:03.717 に答える
29

編集:

両方のアプローチを試した後、パスポートローカル戦略を使用した何らかの理由で、常に除外するアプローチが機能していないことがわかりました。理由はよくわかりません。

だから、これは私が使用することになったものです:

Blogs.findOne({_id: id})
    .populate("user", "-password -someOtherField -AnotherField")
    .populate("comments.items.user")
    .exec(function(error, result) {
        if(error) handleError(error);
        callback(error, result);
    });

常に除外するアプローチには何の問題もありません。何らかの理由でパスポートでは機能しませんでした。私のテストでは、実際にはパスワードが必要なときに除外/含まれていることがわかりました。include alwaysアプローチの唯一の問題は、基本的に、データベースに対して行うすべての呼び出しを実行し、パスワードを除外する必要があることです。これは多くの作業です。


いくつかの素晴らしい答えの後で、これを行うには2つの方法があることがわかりました。「常に含めると除外する」と、「常に除外して含める」です。

両方の例:

常に含めるが、時々除外する例:

Users.find().select("-password")

また

Users.find().exclude("password")

常に説明しますが、例を含めることもあります。

Users.find().select("+password")

ただし、スキーマで次のように定義する必要があります。

password: { type: String, select: false }
于 2012-08-23T18:27:04.827 に答える
4

Blogs.findOne({ _id: id }, { "password": 0 }).populate("user").exec()

于 2016-08-28T15:25:48.387 に答える
3

パスワードフィールドが「password」であると仮定すると、次のことができます。

.exclude('password')

より広範な例がここにあります

これはコメントに焦点を当てていますが、同じ原則です。

これは、MongoDB のクエリで射影を使用し{"password" : 0}、射影フィールドを渡すことと同じです。こちらをご覧ください

于 2012-08-23T17:05:25.537 に答える
3
router.get('/users',auth,(req,res)=>{
   User.findById(req.user.id)
    //skip password
    .select('-password')
    .then(user => {
        res.json(user)
    })
})
于 2019-10-31T04:31:49.193 に答える
0

これは元の質問の結果ですが、これは私が問題を解決しようとして出くわした質問でした...

つまり、パスワードフィールドなしで user.save() コールバックでユーザーをクライアントに送り返す方法です。

ユース ケース: アプリケーション ユーザーは、クライアントからプロファイル情報/設定 (パスワード、連絡先情報など) を更新します。mongoDB に正常に保存されたら、更新されたユーザー情報を応答でクライアントに送り返す必要があります。

User.findById(userId, function (err, user) {
    // err handling

    user.propToUpdate = updateValue;

    user.save(function(err) {
         // err handling

         /**
          * convert the user document to a JavaScript object with the 
          * mongoose Document's toObject() method,
          * then create a new object without the password property...
          * easiest way is lodash's _.omit function if you're using lodash 
          */

         var sanitizedUser = _.omit(user.toObject(), 'password');
         return res.status(201).send(sanitizedUser);
    });
});
于 2016-07-26T21:44:12.600 に答える