Доступ к переменной пароля пользователя с использованием этого экземпляра внутри другой функции - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь аутентифицировать пользователя, но получаю эту ошибку в почтальоне

{
"error": "data and hash arguments required"
}

Моя модель пользователя выглядит следующим образом:

const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const SALT_WORK_FACTOR = 10
const Schema = mongoose.Schema

const UserSchema = new Schema({
  username: { type: String, required: true, index: { unique: true } },
  password: { type: String, required: true }
})
UserSchema.pre('save', function (next) {
  let user = this

  // only hash the password if it has been modified(or is new)
  if (!user.isModified('password')) return next()

  // generate a salt
  bcrypt.genSalt(SALT_WORK_FACTOR, (err, salt) => {
    if (err) return next()

    // hash the password along with our new salt
    bcrypt.hash(user.password, salt, (err, hash) => {
      if (err) return next(err)
      // override the cleartext password with the hashed one
      user.password = hash
      next()
    })
  })
})
UserSchema.methods.comparePassword = (candidatePassword, callback) => {
  console.log('Password', this.password)// undefined
  bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
    callback(err, isMatch)
  })
}
module.exports = mongoose.model('userData', UserSchema, 'userData')

Я понял, что this.password переданоФункция сравнения bcrypt преобразуется в неопределенное. Как я могу получить доступ к переменной пароля, определенной в экземпляре UserSchema выше?

1 Ответ

0 голосов
/ 19 июня 2018

Очевидно, в javascript, this не присваивается значение, пока объект не вызовет функцию, тем самым связав this с владельцем метода (вызывающим объектом).В приведенном выше вопросе я использую es6 функции стрелок, чья this связана с ближайшей окружающей областью (лексической областью), поэтому не может найти свойство password, которое определено в UserSchema , а непривязан к области действия this в функции стрелки.
Пример:

var Utils = {
  printName: function(somename) {
    console.log(somename)
  }
}

var person = {
  firstName: "Gregory",
  lastNames: ["Baltimore", "Barry", "Derrick", "Evanson"],
  fullName: function() {
    this.lastNames.forEach(lastname => {
     //this points to person object
      Utils.printName(this.firstName + " " + lastname) //output Gregory Baltimore Gregory Barry Gregory Derrick Gregory Evanson
    })
  }
}

person.fullName()

Примечание this внутри функции стрелки es6 указывает на объект person, который является его статической областью (лексической).Давайте посмотрим на тот же кусок кода с точки зрения es5

 var Utils = {
      printName: function(somename) {
        console.log(somename)
      }
    }

    var person = {
      firstName: "Gregory",
      lastNames: ["Baltimore", "Barry", "Derrick", "Evanson"],
      fullName: function() {
        this.lastNames.forEach(function(lastname) {
    //this points to global object
          Utils.printName(this.firstName + " " + lastname)  //output undefined Baltimore undefined Barry undefined Derrick undefined Evanson 
        })
      }
    }

    person.fullName()

Вы заметите, что имя напечатано как неопределенное. Это потому, что в es5 this выходит из области видимости и, следовательно, по умолчанию (Причуда Javascript) привязывается к глобальному объекту. В браузере этот глобальный объект - это окно в Nodejs, глобальный объект - это среда Nodejs (среда выполнения), если пользователь не определил ее (например, как при экспорте модуля) Чтобы решить мой вопрося по умолчанию использовал функцию es5, так как свойство пароля связано с глобальным объектом, который я определил как UserSchema. Таким образом, свойство паролябыло правильно решено

 UserSchema.methods.comparePassword = function (candidatePassword, callback) {
  //Now this is bound to the UserSchema object
  bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
    callback(err, isMatch)
  })
}

Более подробно об этом можно узнать здесь Понимание JavaScript «этого» с помощью Clarity и Master It

и здесь также Функции стрелоки ключевое слово "это"

...