Занятие №24 посвящено важнейшему аспекту архитектуры современных корпоративных информационных систем: проектированию надежных интерфейсов взаимодействия с пользователем и эшелонированной системы контроля входных данных. В классических реляционных архитектурах интерфейс пользователя (Frontend) и ядро хранения данных (Backend / СУБД) образуют единый контур защиты, в котором ни один уровень не имеет права слепо доверять другому.
Ключевая дидактическая цель: сформировать у обучающихся устойчивое инженерное понимание концепции «эшелонированной обороны» (Defense in Depth) данных, освоить распределение обязанностей между клиентской валидацией (UX, регулярные выражения, мгновенная обратная связь, блокировка отправки) и серверным контролем СУБД (декларативные ограничения CHECK, уникальные индексы, триггеры BEFORE INSERT/UPDATE, транзакционная изоляция), а также научиться профессионально перехватывать системные исключения СУБД (коды SQLSTATE) и транслировать их в понятные человеку экранные уведомления, исключая уязвимости внедрения SQL-кода.
BEFORE INSERT OR UPDATE.В соответствии с регламентом учебного процесса СИЭУиП занятие рассчитано на 2 академических часа. Ниже приведена поминутная сетка для основного (80 минут) и сокращенного (60 минут) вариантов.
| Этап занятия | Основной (80 мин) | Сокращенный (60 мин) | Ключевое содержание и деятельность преподавателя |
|---|---|---|---|
| 1. Оргмомент и мотивация | 5 минут | 3 минуты | Приветствие, проверка готовности ПК и журнала. Разбор кейса уязвимости: обход клиентского JS через cURL и взлом баланса. Формулировка проблемы урока. |
| 2. Актуализация знаний | 8 минут | 5 минут | Фронтальный экспресс-опрос: ограничения целостности (PRIMARY, UNIQUE, CHECK, FOREIGN KEY), транзакции ACID, почему СУБД отвергает некорректные кортежи. |
| 3. Изложение нового материала | 32 минуты | 25 минут |
Демонстрация интерактивной презентации: • Двухуровневая модель: Frontend UX vs Backend Integrity; • Регулярные выражения в интерфейсах и маски ввода; • Защита от SQL-инъекций: параметризованные запросы (Prepared Statements); • Серверный контроль: триггеры BEFORE и изоляция транзакций; • Перехват исключений SQLSTATE и Error Mapping на клиенте. |
| 4. Инженерный практикум | 23 минуты | 18 минут |
Работа в интерактивном рабочем листе zanyatie.html по 4 дифференцированным сценариям (ИНН корпоративного клиента, банковский перевод, заказ в интернет-магазине, бронирование отеля). Проектирование валидаторов и матриц маппинга SQLSTATE.
|
| 5. Контроль и рефлексия | 8 минут | 6 минут | Разбор слайда 15 (культовый мем xkcd #327 «Bobby Tables»), оценка выполненных работ по 4-балльной рубрике, фиксация домашнего задания. |
| ИТОГО | 80 минут | 60 минут | Полное выполнение дидактических задач в двух таймингах. |
Центральный теоретический посыл занятия: клиентская валидация предназначена для удобства пользователя (User Experience), а серверная валидация — для обеспечения физической выживаемости и целостности базы данных (Data Integrity).
Клиентский уровень выполняется в среде браузера или мобильного приложения на стороне пользователя. Его задачи:
input и blur (зеленая рамка при успехе, красная с текстом ошибки при нарушении формата).disabled) до тех пор, пока все обязательные поля не удовлетворят регулярным выражениям и контрольным суммам.+7 (999) 000-00-00 или ОГРН из 13 цифр).Серверный уровень состоит из API-шлюза (бэкенда) и ядра СУБД:
CHECK (проверка диапазонов, булевых условий и POSIX-регулярок через ~), NOT NULL, UNIQUE, FOREIGN KEY, EXCLUDE USING gist.BEFORE INSERT OR UPDATE FOR EACH ROW, способные проверить остатки на складе, вычислить сложный баланс или отменить операцию с помощью RAISE EXCEPTION.READ COMMITTED, REPEATABLE READ и SERIALIZABLE, а также селекты с блокировкой SELECT ... FOR UPDATE для предотвращения состояния гонки (Race Condition).При нарушении любого правила целостности ядро СУБД генерирует исключение, содержащее стандартный пятисимвольный код SQLSTATE (ISO/IEC 9075):
| Код SQLSTATE | Имя константы в PostgreSQL | Причина возникновения в ядре СУБД | Пользовательское сообщение (UX Error Mapping) |
|---|---|---|---|
23505 |
unique_violation |
Попытка вставки дублирующегося значения в поле с ограничением PRIMARY KEY или UNIQUE. | «Запись с такими данными уже существует в системе. Проверьте уникальные идентификаторы.» |
23514 |
check_violation |
Значение строки не удовлетворило булеву предикату ограничения CHECK. | «Введенное значение не соответствует допустимому формату или диапазону бизнес-правил.» |
23503 |
foreign_key_violation |
Ссылка на несуществующую родительскую запись или попытка удаления связанной сущности. | «Указанный связанный объект не найден в справочнике системы либо используется другими данными.» |
23P01 |
exclusion_violation |
Нарушение ограничения исключения EXCLUDE (например, пересечение временных интервалов брони). | «Выбранный номер/ресурс уже занят на указанные даты. Пожалуйста, выберите другой интервал.» |
40001 |
serialization_failure |
Конфликт параллельных транзакций при уровне изоляции SERIALIZABLE / REPEATABLE READ. | «Операция временно недоступна из-за параллельного изменения данных. Повторите попытку через пару секунд.» |
P0001 |
raise_exception |
Пользовательское исключение, выброшенное серверным PL/pgSQL триггером (например, нет товара на складе). | Текст ошибки из триггера (например: «Недостаточно товара на складе для оформления заказа»). |
ERROR: duplicate key value violates unique constraint "clients_inn_key"). Это грубейшее нарушение информационной безопасности (раскрытие схемы БД и имен таблиц злоумышленнику) и провал интерфейсной эргономики.
Одной из ключевых тем занятия является демонстрация студентам принципа параметризации. В небрежно спроектированных интерфейсах пользовательский ввод конкатенируется прямо в SQL-строку:
// КАТАСТРОФИЧЕСКИЙ АНТИПАТТЕРН (Уязвимость SQL Injection):
String sql = "SELECT * FROM users WHERE login = '" + userLogin + "' AND pass = '" + userPass + "'";
// Если userLogin = "admin' --", весь парольный фильтр отсекается комментарием!
Преподаватель объясняет фундаментальный механизм Prepared Statement:
$1, $2 или ?), строит дерево синтаксического разбора (AST) и фиксирует план выполнения. На этом этапе структура запроса запечатывается навсегда.// ПРОМЫШЛЕННЫЙ ЭТАЛОН (Параметризованный запрос):
PreparedStatement ps = conn.prepareStatement("SELECT id, role FROM users WHERE login = $1 AND pass_hash = $2");
ps.setString(1, userLogin);
ps.setString(2, hashedPass);
ResultSet rs = ps.executeQuery();
| Типовая ошибка студента | В чем проявляется дефект | Педагогический прием и метод устранения |
|---|---|---|
| «Иллюзия клиентской защиты» | Студент пишет сложную валидацию на JavaScript и считает, что базу данных защищать ограничениями больше не нужно. | На глазах у группы преподаватель открывает терминал и с помощью команды curl -X POST ... отправляет на бэкенд невалидные данные в обход браузера, вызывая сбой БД. |
| «Сырой вывод SQL-ошибок» | Студент выводит в alert() или текстовый блок браузера системное сообщение e.getMessage() от JDBC/PostgreSQL. |
Преподаватель объясняет риски Information Disclosure (утечка имен колонок, типов, индексов) и демонстрирует архитектурный паттерн Error Mapper Dictionary. |
| «Неверная обработка Race Condition» | Студент проверяет наличие записи обычным SELECT, а затем делает INSERT, не учитывая параллельных пользователей. |
Разбор классической проблемы Time-of-check to time-of-use (TOCTOU). Демонстрация уникальных индексов, ограничений EXCLUDE и блокировок SELECT FOR UPDATE. |
| «Забытые якоря в регулярных выражениях» | Вместо строгого шаблона ^\d{10}$ студент пишет \d{10}, пропуская строки типа буквы1234567890хвост. |
Разбор символов начала строки (^) и конца строки ($). Тестирование строк с мусорными символами по краям. |
В соответствии с учебным планом СИЭУиП занятие оценивается по 4-балльной шкале:
^ и $, математическая проверка контрольных разрядов (для ИНН), логика мгновенной подсветки полей и превентивная блокировка кнопки Submit при некорректных данных.23505, 23514, 23P01, P0001, 40001), проектирование понятного и безопасного текста уведомления для пользователя без утечки технической информации СУБД.