Продолжайте получать неверные учетные данные при входе в систему node.js Express.js

#javascript #node.js #express

Вопрос:

Я довольно новичок в node.js и пытаясь получить свои учетные данные для входа из базы данных, я могу успешно получить учетные данные для входа из базы данных, но когда я вызываю ее из своего server.js файл, я продолжаю получать неверные учетные данные, даже если это правильные учетные данные. Я был бы признателен, если бы свежие глаза могли взглянуть на это и указать, что я делаю неправильно. Использование базы данных Postgres

 app.post('/api/login', async (req, res) => {
  try {
    const loginCredentials = {
      email: req.body.email,
      password: req.body.password
    }

    if (loginCredentials.email === '' amp;amp; loginCredentials.password === '') {
      return res.status(500).send('Email and Password required')
    }
    if (loginCredentials.email === '' || loginCredentials.password === '') {
      return res.status(500).send('Email and Password required')
    }
    if (loginCredentials.email amp;amp; loginCredentials.password ) {
      // getting credentials from db.login
      const result = await db.login(loginCredentials.email, loginCredentials.password)
      console.log('* '   result)
      if (result) {
        res.status(200).send("Success")
      } else {
        res.status(401).send("Invalid Credentials")
      }
    }
  } catch (e) {
    throw e
  }

 

и вот мой метод входа в бд.

 async function login(email, password) {
  console.debug("login db")
  const query = `SELECT *
                 FROM users
                 WHERE email = $1`
  const client = await pool.connect()
  try {
    await client.query(query, [email], async function (err, result) {
      if (err) {
        throw err
      }
      console.debug('hash: '   result.rows[0].hash)
      console.debug('pass: '   password)

      if (result.rows.length > 0) {
        const user = result.rows[0]
        //role = user.role
        const validPassword =  bcrypt.compare(password, user.hash)
        if (!validPassword){
          console.log('Invalid Credentials')
          return 'Invalid Credentials'
        }else {
          console.debug('success')
          return user
        }
      } else {
        return 'No user in the DB'
      }
    
    })
  } catch (e) {
    throw e
  }
}

 

Ответ №1:

Вы не await compare учитываете результат метода, поэтому validPassword всегда будете неразрешенным Promise , а не результатом.

Добавление await должно это исправить:

 const validPassword = await bcrypt.compare(password, user.hash)
 

ПРАВКА: Я вижу , что вы сверяетесь с if (!validPassword) , что никогда не бывает «правдивым», если validPassword это a Promise . Возможно, вы захотите проверить, какую версию bcrypt вы используете — compare возвращает ли обещание, или это, возможно, старая версия, в которой используется только подпись обратного вызова. В этом случае вам следует либо обновить зависимость bcrypt, либо вместо этого использовать метод обратного вызова: compare(password, user.hash, function(err, validPassword) { /* check validPassword here */ }) .

Возможно, вы также захотите проверить свой поток, вы возвращаете пользователя из client.query обратного вызова, но вы также await принимаете его, но не сохраняете и не возвращаете его возвращаемое значение. У меня нет опыта работы с API Postgres, но похоже, что вы смешиваете обещания (с асинхронным/ожиданием) и обратные вызовы. По моему опыту, всегда одно или другое — вы либо используете поток обратного вызова, либо возвращаете поток обещаний. Если client.query возвращает обещание, оно, вероятно, разрешится с результатами, которые вы сейчас обрабатываете с помощью обратного вызова.

Попробуйте переписать его таким образом:

 async function login(email, password) {
  console.debug("login db")
  const query = `SELECT *
                 FROM users
                 WHERE email = $1`
  const client = await pool.connect()
  try {
    const result = await client.query(query, [email])

    console.debug('hash: '   result.rows[0].hash)
    console.debug('pass: '   password)

    if (result.rows.length > 0) {
      const user = result.rows[0]
      //role = user.role
      const validPassword = await bcrypt.compare(password, user.hash)
      if (!validPassword){
        console.log('Invalid Credentials')
        return 'Invalid Credentials'
      }else {
        console.debug('success')
        return user
      }
    } else {
      return 'No user in the DB'
    }
  } catch (e) {
    throw e
  }
}
 

Еще одно изменение: обратите внимание, что приведенный выше код теперь действительно будет возвращать что-то, либо пользовательскую строку, либо строку. Ранее ваш db.login метод возвращал обещание, которое разрешалось без значения, всегда проваливая следующую if (result) проверку, потому result что есть undefined . Если вы измените свой db.login код на вышеуказанный, if (result) теперь он всегда будет истинным, потому что это либо строка, либо объект пользователя. Возможно, вы захотите throw 'Invalid credentials' и throw 'No user in the DB' вместо этого, и обернуть db.login(..) вызов в try / catch:

 try {
   const result = await db.login(loginCredentials.email, loginCredentials.password)
   res.status(200).send("Success")
}
catch(err) {
   res.status(401).send("Invalid Credentials")
}
 

Комментарии:

1. Большое вам спасибо за ваше время, которое помогло мне. это была моя вина, что я смешал обещание и асинхронное ожидание