Разработка на PHP: Как реализовать метод защиты от повторной отправки формы (Double Submit Cookie или CSRF Token), чтобы избежать дублей в базе данных?

Повторная отправка формы (double submit) — распространённая проблема в веб-разработке, которая приводит к дублированию записей в базе данных. Рассмотрим два основных подхода к её решению на PHP.

## 1. CSRF Token (одноразовый токен)

Это наиболее надёжный метод. Суть: при каждой загрузке формы генерируется уникальный токен, который хранится в сессии и передаётся скрытым полем. После успешной обработки токен уничтожается.

**Генерация токена:**
php
session_start();
if (empty($_SESSION[‘csrf_token’])) {
$_SESSION[‘csrf_token’] = bin2hex(random_bytes(32));
}

**Вставка в форму:**
html
<input type="hidden" name="csrf_token" value="»>

**Проверка при обработке:**
php
session_start();
if (!isset($_POST[‘csrf_token’]) || $_POST[‘csrf_token’] !== $_SESSION[‘csrf_token’]) {
die(‘Недействительный токен. Повторная отправка запрещена.’);
}
// Инвалидируем токен после использования
unset($_SESSION[‘csrf_token’]);
// Далее — запись в базу данных

После успешной обработки выполните редирект (паттерн PRG — Post/Redirect/Get), чтобы предотвратить повторную отправку при обновлении страницы:
php
header(‘Location: /success.php’);
exit;

## 2. Double Submit Cookie

Метод основан на том, что злоумышленник не может читать куки другого домена. Токен одновременно записывается в куку и в скрытое поле формы. При обработке сервер сравнивает их.

php
// Установка куки и поля формы
$token = bin2hex(random_bytes(32));
setcookie(‘csrf_cookie’, $token, [
‘httponly’ => true,
‘samesite’ => ‘Strict’,
‘secure’ => true
]);

html
<input type="hidden" name="csrf_field" value="»>

**Проверка:**
php
if (!isset($_COOKIE[‘csrf_cookie’], $_POST[‘csrf_field’])
|| !hash_equals($_COOKIE[‘csrf_cookie’], $_POST[‘csrf_field’])) {
die(‘Ошибка проверки токена.’);
}

## 3. Дополнительная защита на уровне БД

Даже при использовании токенов рекомендуется добавить уникальный индекс на критичные поля в таблице:
sql
ALTER TABLE orders ADD UNIQUE INDEX idx_unique_order (user_id, product_id, created_at);

Или использовать `INSERT IGNORE` / `ON DUPLICATE KEY UPDATE` в MySQL для атомарной защиты.

## Итог

— **CSRF Token** — лучший выбор для большинства форм: надёжен, прост в реализации.
— **Double Submit Cookie** — подходит для stateless-архитектур (API, микросервисы).
— **PRG-паттерн** обязателен после любой успешной обработки POST-запроса.
— **Уникальные индексы** в БД — последний рубеж защиты от дублей.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.