#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. Большое вам спасибо за ваше время, которое помогло мне. это была моя вина, что я смешал обещание и асинхронное ожидание