#javascript #node.js #postgresql #express
#javascript #node.js #postgresql #выразить
Вопрос:
В node js у меня есть следующий фрагмент кода
const express = require('express');
const pool = require('../db');
const bcrypt = require('bcryptjs');
const router = express.Router();
const { registerValidation } = require('../validation')
const { sendEmail } = require('./sendEmail')
router.post("/", async(req, res) => {
// LETS VALIDATE THE DATA BEFORE MAKE A USER and it comes from validation.js file
const { error } = registerValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
// If the user already exists
pool.query("select email from users where email='" req.body.email "'", function(err, data){
if(data.rows.length > 0) {
return res.status(400).send("This email already exists");
}
})
// Hash password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt);
try{
const { name, username, email, verified, token, recieveEmail, gender } = req.body;
const newUser = await pool.query("INSERT INTO users (name, username, email, verified, token, password, recieveEmail, gender) VALUES($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *",
[name, username, email, verified, token, hashedPassword, recieveEmail, gender]);
const { error } = sendEmail(req.body.email);
if (!error){
return res.status(400).send("Email could not be sent");
}
res.json(newUser.rows);
}catch(err){
console.error(err.message)
}
})
module.exports = router;
Если я попытаюсь использовать дубликат идентификатора электронной почты, который уже существует в таблице users, он показывает сообщение об ошибке, это электронное письмо уже существует, и в то же время оно вставляет данные в таблицу users, отправляет электронное письмо на указанный адрес электронной почты. Это означает, что код все еще выполняется после оператора return .
Мне было интересно, почему он не перестает работать, когда находит оператор return?
Заранее спасибо 🙂
Комментарии:
1.
pool.query()
требуется обратный вызов, потому что это асинхронная операция. Вам нужно переместить весь оставшийся код внутри функции обратного вызова, чтобы он выполнялся после завершения запроса. (Вы также можете переписать свойdb.js
файл, чтобы он возвращал обещание, которое преобразуется в результат запроса иawait
вызов запроса.)2. не делайте
"select email from users where email='" req.body.email "'"
этого, это открывает себя для SQL-инъекции, готовые запросы встроены .. сделайте"select email from users where email=?
, а затемpool.query("...", [req.body.email], func
3. TL; DR :
return
оператор находится внутри функции обратного вызова, а не в функции обработчика маршрута.
Ответ №1:
Рассматриваемая строка находится внутри функции обратного вызова, переданной pool.query()
. Это означает, что выполнение кода, когда оно достигает pool.query()
, немедленно продолжает выполнение, что приводит к поведению, которое вы видите.
Когда обратный вызов возвращается, он просто завершает выполнение самого обратного вызова и выполняется независимо от основной последовательности вашего кода в этот момент.
pool.query("select email from users where email='" req.body.email "'",
// Callback vvvv
function(err, data) {
if (data.rows.length > 0) {
return res.status(400).send("This email already exists");
}
}
);
ПРИМЕЧАНИЕ: Как упоминалось в другом месте, приведенный здесь код представляет собой довольно серьезную уязвимость в системе безопасности, поскольку вы напрямую выполняете входящие, потенциально небезопасные данные запроса при вызове вашей базы данных. Это называется атакой с использованием SQL-инъекций, и вам обязательно следует обратиться к ней, если вы планируете развертывание этого кода.
Комментарии:
1. поле электронной почты;
';DROP TABLE users;--