Как вставить значение в оператор выбора с помощью JavaScript, особенно при использовании Express и Postgres? - PullRequest
0 голосов
/ 05 июля 2019

Как вставить значение в оператор выбора с помощью JavaScript, особенно при использовании express и postgres?

Работают createUser и listAllUsers (для справки приведены ниже).Try / catch работает и выполняет запрос или выдает ошибку для этих двух.

Любая помощь будет принята с благодарностью!

При использовании Postman вывод, который я получаю, когда яотправить get (localhost: 4000 / user / id со значением ключа user_id = 3 x-www-formurlencoded key) будет ...

{
    "name": "error",
    "length": 90,
    "severity": "ERROR",
    "code": "42601",
    "position": "37",
    "file": "scan.l",
    "line": "1134",
    "routine": "scanner_yyerror"
}

И в терминале это показывает следующее (перехвачено с моей консоли.log).

3
QUERY:  SELECT * FROM users WHERE user_id = ${user_id}

Когда я пользователь curl, он говорит то же самое в терминале.Вот команда curl и putput…

curl -X GET localhost:4000/user/3

{"name": "error", "length": 90, "severity": "ERROR", "code": "42601", "position":" 37 "," file ":" scan.l "," line ":" 1134 "," рутина ":" scanner_yyerror "} ww10sc2353621: ~ james.mcgreggor $ curl -X GET localhost: 4000 / user / 3

В конечном итоге те 3, которые я передаю как user_id, не подставляются в оператор выбора.Это моя проблема.Я не могу понять, как правильно это сделать.Должен ли я использовать этот подход или попытаться передать его в качестве параметра в URL-адресе?

Это из моего файла классов пользователя (User.js)

const db = require('../connectors/db.js');
class User {

  constructor(id, user_id, first_name, middle_initial, last_name, email, type) {
    this.id = id;
    this.first_name = first_name;
    this.middle_initial = middle_initial;
    this.last_name = last_name;
    this.email = email;
    this.type = type;
    this.user_id = user_id;
  }

  static newUser(user_id, first_name, middle_initial, last_name, email, type) {
     return db.one(`
      INSERT INTO users ("user_id", "first_name", "middle_initial", "last_name", "email", "type")
      VALUES ('${user_id}', '${first_name}', '${middle_initial}', '${last_name}', '${email}', '${type}')
  returning id
      `)
  }

  static async allUsers() {
    const findAllQuery = 'SELECT * FROM users;';
    return db.query(findAllQuery)
  }

  static async selectUser(user_id) {
    console.log(user_id);
    const findOneQuery = 'SELECT * FROM users WHERE user_id = ${user_id}';
    return db.query(findOneQuery)
  }
}

module.exports = User;

Этоиз моего файла маршрутов (Routes.js)

const express = require('express');
const dataFunctions = require('./catalog.js');

const AppRouter = express.Router();

AppRouter.post('/user', dataFunctions.createUser);
AppRouter.get('/users', dataFunctions.listAllUsers);
AppRouter.get('/user/:id', dataFunctions.listUserByUserID);
AppRouter.delete('/user/:id', dataFunctions.deleteUserByUserID);

module.exports = AppRouter;

Это из моего каталога (Routes.js)

const Users = require('../models/users.js')

// Create

async function createUser(req, res) {
  try {
  console.log(req.body);
  const userId = await Users.newUser(req.body.user_id, req.body.first_name, req.body.middle_initial, req.body.last_name, req.body.email, req.body.type)
 res.status(201).send(`User ID: ${userId.id}`);
  } catch(error) {
    res.status(400).send(error);
  }
}

// List all

async function listAllUsers(req, res) {
  try {
  const userList = await Users.allUsers();
  console.log(userList);
  res.status(200).send(userList);
  } catch(error) {
    res.status(400).send(error);
  }
}

// List by ID

async function listUserByUserID(req, res) {
  try {
  const userList = await Users.selectUser(req.body.user_id);
  console.log(userList);
  res.status(200).send(userList);
  } catch(error) {
    res.status(400).send(error);
  }
}

module.exports = {
  createUser,
  listAllUsers,
  listUserByUserID
}

Ответы [ 3 ]

1 голос
/ 12 июля 2019

Никогда не используйте конкатенацию строк для запросов, у вас уже есть механизм, называемый подготовленный оператор, сигнатура типа

.query('SELECT * FROM `books` WHERE `author` = ?', ['David'])

Он будет очищать ввод для вас и частично предотвращать атаки sql-инъекций, также всегда выполнять проверку входных значений,И если вы не хотите использовать ORM, например typeorm, Sequelize, вы можете использовать knex.js, который может создавать только строки запросов и полностью управлять взаимодействием БД

0 голосов
/ 24 июля 2019

Вы никогда не должны вставлять значения непосредственно в ваш запрос таким образом. Рассмотрим пример:

db.query(`
  INSERT INTO messages (message, username)
  VALUES ('${message}', '${username}')
`);

Если username было моим аутентифицированным именем пользователя, но message было любым значением, которое я ввел в пользовательский интерфейс, я мог бы притвориться кем-то другим, отправив сообщение вроде: I am stupid', 'someone_else') --

SQL будет выглядеть так:

INSERT INTO messages (message, username)
VALUES ('I am stupid', 'someone_else') --', 'my_username')

Бит --', 'my_username') рассматривается как комментарий, поэтому выглядит как someone_else said I am stupid. Это одна из наиболее распространенных и легко эксплуатируемых уязвимостей в веб-приложениях.

Решение 1

Вы можете параметризировать свой запрос:

db.query(`
  INSERT INTO messages (message, username)
  VALUES (?, ?)
`, [message, username]);

Это безопасно, но труднее читать (по моему мнению), и вы должны быть очень осторожны, чтобы всегда делать это последовательно.

Решение 2

https://www.atdatabases.org предоставляет API-интерфейсы для баз данных, которые относительно просты в использовании и полностью защищены от такого рода атак. Вы бы просто сделали:

import connect, {sql} from '@databases/pg';

const db = connect();

db.query(sql`
  INSERT INTO messages (message, username)
  VALUES (${message}, ${username})
`);

для безопасного выполнения того же запроса. Тег sql обеспечивает правильную обработку / экранирование данных, а @databases/pg автоматически заставляет вас всегда добавлять тег sql. Нотабене тогда вокруг параметров нет кавычек.

0 голосов
/ 05 июля 2019

Вместо использования одинарных кавычек в запросе выбора в статическом асинхронном selectUser используйте ``.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...