Когда говорят про безопасность, обычно вспоминают токены, шифрование, роли и права доступа. Разберём практический слой безопасности 👇
-
1️⃣ Идемпотентность: повтор не должен ломать данные
Идемпотентность - это когда один и тот же запрос можно выполнить несколько раз, но результат будет таким, будто он выполнен один раз. Пример: пользователь нажал «Оплатить», интернет моргнул, приложение отправило запрос повторно. Без защиты можно получить:
- 🔹 две оплаты;
- 🔹 два заказа;
- 🔹 двойное списание бонусов;
- 🔹 повторную отправку письма или SMS.
Что делать на практике:
- 🔹 использовать
idempotency_key; - 🔹 сохранять ключ вместе с результатом операции;
- 🔹 при повторе возвращать уже созданный результат;
- 🔹 ставить уникальные ограничения в базе.
-
2️⃣ Антидубли: одно событие - одна обработка
Дубли появляются везде: вебхуки, очереди, ретраи, мобильные клиенты, внешние API. Например, платёжная система может дважды прислать событие «оплата успешна». Это нормально. Ненормально - дважды выдать товар. Что помогает:
- 🔹 хранить
event_idвходящего события; - 🔹 проверять, обрабатывали его или нет;
- 🔹 делать проверку и сохранение атомарно;
- 🔹 использовать уникальные индексы.
Простое правило:
- - если
event_idуже был - игнорируем; - - если новый - сохраняем и обрабатываем.
Важно: антидубли должны работать и при параллельной обработке, когда два воркера одновременно взяли одно событие.
- 🔹 хранить
-
3️⃣ Rate limiting: не даём себя положить
Rate limiting - это ограничение частоты запросов. Он защищает не только от атак, но и от обычных багов: клиент зациклился, бот спамит форму, пользователь 20 раз запросил SMS-код. Где лимиты обязательны:
- 🔹 логин;
- 🔹 регистрация;
- 🔹 восстановление пароля;
- 🔹 отправка SMS/email-кодов;
- 🔹 публичные API;
- 🔹 поиск;
- 🔹 экспорт данных;
- 🔹 дорогие AI-запросы.
-
4️⃣ Очереди задач: не делаем всё в одном запросе
Плохой сценарий: создать заказ → списать оплату → отправить письмо → обновить CRM → вызвать 3 внешних API Если один сервис завис - пользователь ждёт, запрос падает, ретраи создают хаос. Лучше так: в запросе быстро фиксируем действие, а тяжёлую работу отправляем в очередь.
Очереди помогают:
- 🔹 переживать всплески нагрузки;
- 🔹 повторять задачи при временных сбоях;
- 🔹 ограничивать параллельность;
- 🔹 не терять события;
- 🔹 изолировать внешние сервисы.
-
5️⃣ Логирование: чтобы понимать, что произошло
Логи нужны не «для галочки». Они должны помогать расследовать инциденты. Хороший лог отвечает:
- 🔹 кто сделал действие;
- 🔹 когда;
- 🔹 откуда;
- 🔹 какой
request_id; - 🔹 какой endpoint;
- 🔹 чем закончилось;
- 🔹 какая ошибка.
Что нельзя писать в логи:
- • пароли;
- • токены;
- • SMS-коды;
- • секретные ключи;
- • банковские данные;
- • лишние персональные данные.
Логи должны помогать тушить пожар, а не создавать новый.
-
6️⃣ Алерты: узнаём о проблеме раньше пользователей
Если что-то сломалось, команда должна узнать об этом не из чата поддержки. На что ставить алерты:
- 🔹 рост 5xx ошибок;
- 🔹 всплеск ошибок логина;
- 🔹 рост времени ответа;
- 🔹 переполнение очередей;
- 🔹 много задач в retry/dead letter;
- 🔹 резкий рост отправки SMS;
- 🔹 ошибки оплат;
- 🔹 падение внешних интеграций;
- 🔹 подозрительная активность по API.
Надёжная система - не та, где ошибок не бывает. Надёжная система - та, где ошибка не превращается в катастрофу.



Дискуссия