<small>Предыдущие статьи:

- ➡️ [Раздел 21. Типы контроллеров](/docs/21-controllers)
- ➡️ [Раздел 22. Структура фронтенд части](/docs/22-layouts)
- ➡️ [Раздел 23. Выбор js-оболочки](/docs/23-js)
</small>
# SLOT-H: Динамическая подпись

В системе реализован механизм динамической подписи для защиты запросов от CSRF-атак и подмены данных. Подпись генерируется на сервере и передаётся на фронтенд, а затем возвращается с каждым запросом для верификации.

---

## Принцип работы

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

Если подписи совпадают - запрос считается валидным. Если подпись отсутствует или не совпадает - запрос отвергается.

Подпись обновляется при каждом запросе, что делает невозможным повторное использование старой подписи.

---

## Хранение

Подпись хранится в сессии пользователя. Для её получения и обновления используется объект `Request`:

```php
self::_VERIFY_ = 'verifyHash';
$_SESSION[self::_VERIFY_] = md5(time() . rand(1000, 9999));
```
На фронтенд подпись передаётся в поле sign ответа. Для API-запросов подпись добавляется в тело ответа автоматически.

## Передача подписи на фронтенд
Подпись передаётся в ответе сервера в поле sign. Для веб-страниц подпись автоматически добавляется в сессию и доступна через механизмы фронтенда. Для API-запросов подпись включается в JSON-ответ.

Пример ответа API:

```json
{
    "status": "data",
    "data": {...},
    "message": false,
    "sign": "f8cbc97de21289267b415a035419897b"
}
```
Фронтенд извлекает подпись из ответа и сохраняет её для следующего запроса.

## Проверка подписи
Проверка выполняется в классе Request при обработке входящего запроса. Для POST-запросов проверяется наличие поля _sign_ и его соответствие значению в сессии.

```php
if (!isset($_REQUEST['_sign_']) || $_SESSION[self::_VERIFY_] != $_REQUEST['_sign_']) {
    // подпись невалидна - запрос отвергается
}
```
В случае невалидной подписи все параметры запроса обнуляются, а запрос считается недействительным.

## Обновление подписи на фронтенде
При загрузке страницы подпись передаётся как значение js-переменной alfaFooter. Любой API-запрос (включая плановый пинг) получает в ответе актуальную подпись и обновляет alfaFooter.

Таким образом, максимальное время жизни подписи ограничено 30 секундами - периодом планового пинга. При этом подпись может обновляться чаще, если действие пользователя инициирует другой API-запрос.

## Отключение проверки
Проверка подписи может быть отключена через конфигурацию:

```php
define('IGNORE_SIGN', true);
```
Этот флаг используется в режиме разработки, когда необходимо упростить тестирование. В боевом режиме IGNORE_SIGN должен быть false.

**Важно**: отключение проверки подписи снижает защиту системы и не рекомендуется для production-среды.

## Особенности реализации
Механизм подписи позволяет защитить систему от CSRF-атак без необходимости использовать дополнительные библиотеки и усложнять код. Он встроен в ядро системы и работает автоматически для всех POST-запросов.

Для GET-запросов проверка подписи не выполняется, так как они не изменяют состояние системы.

Подпись не зависит от пользователя напрямую - она привязана к сессии, что делает её защищённой от подмены. При смене сессии (перелогинивании) подпись пересоздаётся автоматически.

---

## Что дальше?

- ➡️ [Раздел 25. Защита доступа](/docs/25-security-access)
- ➡️ [Раздел 26. Принцип локализации](/docs/26-localization-principle)
- ➡️ [Раздел 27. Запуск сервера очередей](/docs/27-queue-start)
