🛡 Глубокая безопасность: не только пароли и HTTPS
Когда говорят про безопасность, обычно вспоминают токены, шифрование, роли и права доступа.
Разберём практический слой безопасности 👇
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.
Надёжная система - не та, где ошибок не бывает.
Надёжная система - та, где ошибка не превращается в катастрофу.
Когда говорят про безопасность, обычно вспоминают токены, шифрование, роли и права доступа.
Разберём практический слой безопасности 👇
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.
Надёжная система - не та, где ошибок не бывает.
Надёжная система - та, где ошибка не превращается в катастрофу.