programing

Mongoose/MongoDB의 비밀번호 필드를 보호하여 컬렉션을 채울 때 쿼리로 반환되지 않도록 하려면 어떻게 해야 합니까?

closeapi 2023. 3. 22. 21:13
반응형

Mongoose/MongoDB의 비밀번호 필드를 보호하여 컬렉션을 채울 때 쿼리로 반환되지 않도록 하려면 어떻게 해야 합니까?

컬렉션/스케마가 두 개 있다고 가정합니다.하나는 사용자 이름과 비밀번호 필드가 있는 Users Schema입니다.다음으로 작성자 필드의 사용자 스키마를 참조하는 블로그 스키마가 있습니다.몽구스를 이용해서 이렇게 하면

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

블로그 문서와 사용자도 기입합니다만, Mongoose/MongoDB가 패스워드 필드를 반환하지 않도록 하려면 어떻게 해야 합니까?암호 필드가 해시되었지만 반환되지 않아야 합니다.

비밀번호 필드를 생략하고 간단한 쿼리에서 나머지 필드를 반환할 수 있지만 poople을 사용하여 반환하려면 어떻게 해야 합니까?또, 우아한 방법이 있을까요?

또한 사용자가 로그인하거나 암호를 변경할 때처럼 암호 필드를 입력해야 하는 경우도 있습니다.

필드의 속성을 사용하여 스키마 정의 수준에서 기본 동작을 변경할 수 있습니다.

password: { type: String, select: false }

필요에 .find ★★★★★★★★★★★★★★★★★」populate 콜.'+password' §:

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

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

Schema 옵션을 사용하여 JohnnyHKs에 답변하는 것이 아마도 여기에 가는 방법일 것입니다.

, 「 」, 「 」라고 하는 도 주의해 주세요.query.exclude()2.x 합니다.

편집:

두 가지 방법을 모두 시도해 본 결과, 여권-로컬 전략을 사용하는 어떤 이유로든 제외 방법이 항상 효과가 없다는 것을 알게 되었습니다.왜 그런지 잘 모르겠습니다.

결국 이렇게 된 겁니다.

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

exclude 어프로치에는 문제가 없습니다.그것은 어떤 이유로든 여권에서 동작하지 않았을 뿐이고, 테스트 결과 패스워드는 실제로 제가 원할 때 제외/포함되어 있었습니다.include always 접근법의 유일한 문제는 기본적으로 데이터베이스에 대한 모든 호출을 검토하고 많은 작업이 필요한 비밀번호를 제외해야 한다는 것입니다.


몇 가지 훌륭한 답변을 한 후 이 작업을 수행하는 두 가지 방법이 있다는 것을 알게 되었습니다. "항상 포함시키고 때로는 제외시키고"와 "항상 포함시키고 포함시키고"입니다.

양쪽의 예를 다음에 나타냅니다.

include always but exclude의 예:

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

또는

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

exclude는 항상 사용되지만 경우에 따라서는 다음과 같은 예를 포함합니다.

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

단, 스키마에서 정의해야 합니다.

password: { type: String, select: false }

다음과 같이 스키마를 사용하여 이를 실현할 수 있습니다.

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

User.find().select('-password')정답입니다.추가할 수 없습니다.select: false[스키마] (스키마)

REST JSON 응답의 암호 필드를 숨기기 위해 사용 중입니다.

UserSchema.methods.toJSON = function() {
 var obj = this.toObject(); //or var obj = this;
 delete obj.password;
 return obj;
}

module.exports = mongoose.model('User', UserSchema);

스키마 구성에 몇 가지 설정을 추가하여 다른 방법을 찾았습니다.

const userSchema = new Schema({
    name: {type: String, required: false, minlength: 5},
    email: {type: String, required: true, minlength: 5},
    phone: String,
    password: String,
    password_reset: String,
}, { toJSON: { 
              virtuals: true,
              transform: function (doc, ret) {
                delete ret._id;
                delete ret.password;
                delete ret.password_reset;
                return ret;
              }

            }, timestamps: true });

toJ에 변환 기능을 추가함으로써제외할 필드 이름이 있는 SON 개체.문서에 기재된 바와 같이:

일부 중요한 정보를 삭제하거나 사용자 지정 개체를 반환하는 등의 기준에 따라 결과 개체를 변환해야 할 수 있습니다.에서는, 의 「」를 합니다.transform★★★★★★ 。

const userSchema = new mongoose.Schema(
  {
    email: {
      type: String,
      required: true,
    },
    password: {
      type: String,
      required: true,
    },
  },
  {
    toJSON: {
      transform(doc, ret) {
        delete ret.password;
        delete ret.__v;
      },
    },
  }
);

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

password: { type: String, select: false }인증에 패스워드가 필요한 경우에도 패스워드는 제외된다는 점에 유의해 주십시오.그러니 네가 원하는 대로 할 수 있도록 준비해라.

비밀번호 필드가 "비밀번호"인 경우 다음 작업을 수행할 수 있습니다.

.exclude('password')

여기에 더 광범위한 가 있습니다.

그것은 댓글에 초점을 맞췄지만, 게임에서는 같은 원리입니다.

하여 MongoDB를 통과하는 것과 .{"password" : 0}투사 필드에 있습니다.여기를 참조해 주세요.

router.get('/users',auth,(req,res)=>{
   User.findById(req.user.id)
    //skip password
    .select('-password')
    .then(user => {
        res.json(user)
    })
})

DocumentToObjectOptions 개체를 schema.toJSON() 또는 schema.toObject()에 전달할 수 있습니다.

@types/mongoose에서 TypeScript 정의를 참조하십시오.

 /**
 * The return value of this method is used in calls to JSON.stringify(doc).
 * This method accepts the same options as Document#toObject. To apply the
 * options to every document of your schema by default, set your schemas
 * toJSON option to the same argument.
 */
toJSON(options?: DocumentToObjectOptions): any;

/**
 * Converts this document into a plain javascript object, ready for storage in MongoDB.
 * Buffers are converted to instances of mongodb.Binary for proper storage.
 */
toObject(options?: DocumentToObjectOptions): any;

DocumentToObjectOptions에는 문서를 javascript 객체로 변환한 후 커스텀 함수를 실행하는 변환 옵션이 있습니다.여기서 필요에 맞게 속성을 숨기거나 수정할 수 있습니다.

예를 들어 schema.toObject()를 사용하고 있으며 사용자 스키마에서 비밀번호 경로를 숨기려고 합니다.모든 toObject() 호출 후에 실행되는 일반적인 변환 함수를 설정해야 합니다.

UserSchema.set('toObject', {
  transform: (doc, ret, opt) => {
   delete ret.password;
   return ret;
  }
});

이것은 원래의 질문에 대한 귀결이지만, 이것은 내가 문제를 해결하려다 마주친 질문이다.

즉, 패스워드 필드를 사용하지 않고 user.save() 콜백 내의 클라이언트에 사용자를 되돌리는 방법.

사용 예: 어플리케이션 사용자는 클라이언트로부터의 프로파일 정보/설정(패스워드, 연락처 정보, 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);
    });
});

해결책은 일반 텍스트 암호를 저장하지 않는 것입니다.bcrypt 또는 password-hash와 같은 패키지를 사용해야 합니다.

패스워드를 해시하기 위한 사용 예:

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

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

    console.log(hashedPassword); // sha1$3I7HRwy7$cbfdac6008f9cab4083784cbd1874f76618d2a97

패스워드를 확인하기 위한 사용 예:

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

var hashedPassword = 'sha1$3I7HRwy7$cbfdac6008f9cab4083784cbd1874f76618d2a97';

console.log(passwordHash.verify('password123', hashedPassword)); // true
console.log(passwordHash.verify('Password0', hashedPassword)); // false
const { password,  ...others } = user._doc;

이렇게 보냅니다.

res.status(200).json(others);

*** 이에 대한 두 가지 솔루션이 있습니다.

// OPT: 1

/** If you print these params, the doc and ret are the same objects
 * and opt is another object with special params (only details): */

userSchema.set('toJSON', {
    transform: function(doc, ret, opt) {
        console.log("DOC-RET-OPT", {
            doc,
            ret,
            opt
        });
        // You can remove the specific params with this structure
        delete ret['password'];
        delete ret['__v'];
        return ret;
    }
});

// REMEMBER: You cannot apply destructuring for the objects doc or ret...

// OPT: 2

/* HERE: You can apply destructuring object 'cause the result
* is toObject instance and not document from Mongoose... */

userSchema.methods.toJSON = function() {
    const {
        __v,
        password,
        ...user
    } = this.toObject();
    return user;
};

// NOTE: The opt param has this structure:
opt: {
    _calledWithOptions: {},
    flattenDecimals: true,
    transform: [Function: transform],
    _isNested: true,
    json: true,
    minimize: true
}

언급URL : https://stackoverflow.com/questions/12096262/how-to-protect-the-password-field-in-mongoose-mongodb-so-it-wont-return-in-a-qu

반응형