Как стать автором
Обновить

Low-code API: Как ваш разработчик может разорить вас одной строчкой кода (почему корзина — это минное поле)

Уровень сложностиСредний
Время на прочтение3 мин
Количество просмотров7.5K

Привет, друзья!
Вы же любите no-code/low-code, правда? Кликаете мышкой, перетаскиваете блоки, пьёте капучино — и вуаля, ваше приложение готово! Но стоп. А что, если ваш "волшебный" разработчик на low-code случайно (или специально?) сделал так, что любой школьник может купить у вас iPhone за 10 рублей? Давайте разберёмся, как это возможно, и почему выбор разработчика — это как выбор зубного врача: если ошибётесь, будет больно.

История одной корзины, или почему ваш магазин — не благотворительный фонд

Представьте: у вас есть интернет-магазин. Товары, корзина, заказы — всё как у людей. Всё работает на low-code платформе, чтобы сэкономить бюджет. Но вдруг вы замечаете, что дорогие товары улетают со склада, а деньги не приходят. В чём подвох?

Всё дело в том, как передаются данные о заказе.

❌ Пример "гениального" кода (так делать нельзя!):

Ваш разработчик настроил API так, что клиент сам указывает цену товара. Выглядит это примерно так:
Метод POST /orders


{  
  "product_id": "123",  
  "quantity": 1,  
  "price": 1000 // Ой, а кто это контролирует?  
}

Или например, в вашем приложении при тапе на кнопку "Оформить заказ", вы запускаете цикл и записыавете каждую строку заказа в Supabase (no-code/low-code backend на базе PostgreSQL), указывая product_id, quantity, price.

Что происходит:
Злоумышленник перехватывает API и меняет price на 10 рублей, отправляет запрос — и получает товар за копейки. Ваш магазин превращается в филиал "Пятёрочки" с акцией "Всё за 10 рублей".

Как это исправить? Секреты правильных таблиц и API

🔑 Применая структура данных:

  1. Таблица products:

    • id (уникальный код товара)

    • name

    • price (хранится ТОЛЬКО здесь!)

  2. Таблица orders:

    • id (UUID)

    • total (сумма заказа)

  3. Таблица order_items:

    • order_id (ссылка на заказ)

    • product_id (ссылка на товар)

    • quantity

    • price (цена на момент заказа, берётся из products)

✅ Пример умного API:

Клиент отправляет только ID товара и количество. Цену знает только сервер!

{  
  "items": [  
    { "product_id": "8719", "quantity": 2 },  
    { "product_id": "8720", "quantity": 3 }  
  ]  
}

Пример API в Supabase

Давайте рассмотрим на примере Supabase, который кстати можно установить на свой сервер. Для простоты будем использовать обычные функции в базе данных.

  1. Создадим SQL-функцию bulk_insert_order_items.
    Эта функция будет принимать на входе id заказа и список позиций заказа (только id товара и количество. Без указания цен!). А внутри она будет брать из базы цены на товары и считать стоимость по каждой позиции, а также стоимость всего заказа.

CREATE OR REPLACE FUNCTION bulk_insert_order_items(
    p_order_id UUID,
    p_items JSONB
) RETURNS VOID AS $$
DECLARE
    v_total REAL := 0;
    v_item RECORD;
BEGIN
    -- Перебираем товары и сохраняем их в order_items
    FOR v_item IN SELECT * FROM jsonb_to_recordset(p_items) AS (
        product_id BIGINT,
        quantity REAL
    ) LOOP
        INSERT INTO order_items (order_id, product_id, quantity, price)
        SELECT p_order_id, v_item.product_id, v_item.quantity, p.price
        FROM products p
        WHERE p.id = v_item.product_id
        RETURNING price * v_item.quantity INTO v_total;
    END LOOP;
    
    -- Обновляем сумму заказа
    UPDATE orders
    SET total = COALESCE(total, 0) + v_total
    WHERE id = p_order_id;
END;
$$ LANGUAGE plpgsql;

2. Проверим работу функции непосредственно через SQL:

select bulk_insert_order_items(
    '0f0cbe98-535f-44e4-b842-2c1f06840e9a',  -- Замените на валидный UUID заказа
    '[{"product_id": 8719, "quantity": 2}, {"product_id": 8720, "quantity": 3}]'::jsonb  -- Замените на ваши данные
);

3. Также вы можете использовать Edge Functions, если требуется более сложная логика или интеграция с внешними сервисами. Преимущество Edge Functions в том, что они позволяют контролировать каждый шаг обработки, добавлять кастомные проверки и легко масштабировать решение, что может быть удобнее, если нужна дополнительная гибкость по сравнению с SQL-функциями.

4. Supabase автоматически генерирует API для вызова этой функции. Указываем номер заказа и передаем список товаров и количество, без цен!

curl -X POST 'https://yourproject.supabase.co/rest/v1/rpc/bulk_insert_order_items' \
-d '{
  "p_order_id": "0f0cbe98-535f-44e4-b842-2c1f06840e9a",
  "p_items": "[{\"product_id\": 8719, \"quantity\": 2}, {\"product_id\": 8720, \"quantity\": 3}]"
}' \
-H "Content-Type: application/json" \
-H "apikey: SUPABASE_KEY" \
-H "Authorization: Bearer SUPABASE_KEY"

Совет заказчикам: Как не нанять "разрушителя бизнесов"

  1. Спросите: «Где считается цена — на сервере или в телефоне клиента?». Если ответ «В интерфейсе», бегите быстрее света.

  2. Проверьте API: Если в запросе есть price, discount или total — это красная лампочка.

  3. Требуйте логов: Все операции с деньгами должны логироваться на сервере.

  4. Узнайте ИТ-бэкграунд вашего специалиста: имеет ли ваш no-code / low-code- разработчик опыт работы разработчиком или системным аналитиком.

Итог: Low-code — это круто, но...

...если ваш разработчик пришел в low-code без базовых принципов разработки ПО, будьте готовы к небезопасным и не оптимизированным приложениям.

P.S. Если после прочтения статьи вы подумали: «А мой API тоже дырявый?» — давайте проверим! Пишите мне в Telegram: @kirilkindn. Устроим вашему приложению «тест-драйв» — бесплатно, с кофе и полезными фидбеками 😉.

Теги:
Хабы:
Всего голосов 13: ↑1 и ↓12-10
Комментарии9

Публикации

Ближайшие события