Как защитить поле пароля в Mongoose / MongoDB, чтобы оно не возвращалось в запросе при заполнении коллекций?



Предположим, у меня есть две коллекции/схемы. Один из них-схема пользователей с полями имени пользователя и пароля, затем у меня есть схема блогов, которая имеет ссылку на схему пользователей в поле автора. Если я использую Мангуста, чтобы сделать что-то вроде



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


У меня будет документ блога и пользователь заполнены тоже, но как я могу предотвратить Мангуст/MongoDB от возврата поля пароля? Поле пароля хэшируется, но оно не должно быть возвращено.



Я знаю, что могу опустить поле пароля и возвращает остальные поля в простом запросе, но как это сделать с помощью заполнения. Кроме того, есть ли элегантный способ сделать это?



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

1369   10  

10 ответов:

.populate('user' , '-password')

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

JohnnyHKs ответ с использованием параметров схемы, вероятно,путь сюда.

также обратите внимание, что query.exclude() существует только в 2.х филиал.

вы можете изменить поведение по умолчанию на уровне определения схемы с помощью select поля:

password: { type: String, select: false }

затем вы можете вытащить его в find и populate вызовы через выбор поля как '+password'. Например:

Users.findOne({_id: id}).select('+password').exec(...);

Edit:

попробовав оба подхода, я обнаружил, что подход exclude always не работал для меня по какой-то причине, используя стратегию passport-local, на самом деле не знаю, почему.

Итак, вот что я в конечном итоге с помощью:

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

нет ничего плохого в исключении всегда подход, он просто не работал с паспортом по какой-то причине, мои тесты сказали мне, что на самом деле пароль был исключен / включен, когда я хотел. Единственная проблема с включить всегда подход заключается в том, что мне в основном нужно пройти через каждый вызов, который я делаю в базу данных, и исключить пароль, который является большой работой.


после пары ответов я узнал, что есть два способа сделать это, "всегда включать и исключать иногда" и "всегда исключать и включать иногда"?

пример как:

включить всегда, но иногда исключить пример:

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

или

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

exlucde всегда, но иногда включают пример:

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

но вы должны определить в схеме:

password: { type: String, select: false }

User.find().select('-password') Это правильный ответ. Вы не можете добавить select: false на схему, так как он не будет работать, если вы хотите войти.

предполагая, что ваше поле пароля - это "пароль", вы можете просто сделать:

.exclude('password')

есть более обширный пример здесь

это сосредоточено на комментариях, но это тот же принцип в игре.

это то же самое, что использовать проекцию в запросе в MongoDB и передавать {"password" : 0} в поле проекция. Смотрите здесь

вы можете добиться этого, используя схему, например:

const UserSchema = new Schema({/* */})

UserSchema.set('toJSON', {
    transform: function(doc, ret, opt) {
        delete ret['password']
        return ret
    }
})

const User = mongoose.model('User', UserSchema)
User.findOne() // This should return an object excluding the password field

решение состоит в том, чтобы никогда не хранить пароли открытого текста. Вы должны использовать пакет, как [bcrypt]1 или [password-hash]2.

пример использования для хэширования пароля:

 var passwordHash = require('password-hash');

    var hashedPassword = passwordHash.generate('password123');

    console.log(hashedPassword); // sha1I7HRwy7$cbfdac6008f9cab4083784cbd1874f76618d2a97

пример использования для проверки пароля:

var passwordHash = require('./lib/password-hash');

var hashedPassword = 'sha1I7HRwy7$cbfdac6008f9cab4083784cbd1874f76618d2a97';

console.log(passwordHash.verify('password123', hashedPassword)); // true
console.log(passwordHash.verify('Password0', hashedPassword)); // false

Это скорее следствие к исходному вопросу, но это был вопрос, с которым я столкнулся, пытаясь решить мою проблему...

а именно, как отправить пользователя обратно клиенту в Пользователь.сохранить () обратный вызов без поля пароля.

Use case: пользователь приложения обновляет информацию о своем профиле / настройки из клиента (пароль, контактная информация, whatevs). Вы хотите отправить обновленную информацию о пользователе обратно клиенту в ответе, как только он успешно сохранен в 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);
    });
});

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

при использовании password: { type: String, select: false } вы должны иметь в виду, что он также будет исключать пароль, когда нам это нужно для аутентификации. Так что будьте готовы справиться с этим, как вы хотите.

Comments

    Ничего не найдено.