Параметр forbidNonWhitelisted применяется в механизме
валидации объектов, когда входные данные проходят проверку через схемы,
описанные с помощью декораторов class-validator. Он
используется в связке с преобразованием и фильтрацией входящих данных и
играет ключевую роль в защите приложения от «лишних» или неожиданных
полей.
В типичном сценарии обработки входных данных система принимает
объект, преобразует его в экземпляр класса и затем проверяет
соответствие правилам, заданным через декораторы
(@IsString, @IsNumber,
@IsOptional и т.д.). Однако даже при наличии строгой
валидации объект может содержать дополнительные поля, не описанные в
DTO. Именно здесь вступает в работу механизм whitelist и параметр,
который управляет его строгим поведением.
Механизм whitelist отвечает за удаление всех свойств объекта, которые не описаны в классе-валидаторе. То есть если входящий объект содержит поля, отсутствующие в DTO, они автоматически отбрасываются до этапа валидации.
Однако существует два варианта поведения:
За строгий режим отвечает параметр
forbidNonWhitelisted.
При включённом whitelist и активированном
forbidNonWhitelisted процесс обработки входных данных
выглядит следующим образом:
Таким образом, forbidNonWhitelisted не просто фильтрует
данные, а полностью блокирует запрос при нарушении схемы.
Если whitelist включён, но forbidNonWhitelisted не
активирован, происходит более мягкая обработка:
Такой режим подходит для ситуаций, где допустима «гибкость» входных данных, но не требуется строгая фиксация структуры.
Ключевая концептуальная разница заключается в реакции системы на «лишние» данные:
| Режим | Поведение |
|---|---|
| whitelist без forbidNonWhitelisted | удаление лишних полей |
| whitelist + forbidNonWhitelisted | ошибка при наличии лишних полей |
| без whitelist | лишние поля игнорируются валидацией |
Строгий режим особенно важен в API, где структура входных данных должна быть жёстко фиксирована. Например:
В таких случаях любые дополнительные поля могут свидетельствовать о:
import { IsString, IsNumber } from 'class-validator';
export class CreateUserDto {
@IsString()
name: string;
@IsNumber()
age: number;
}
Входящий объект:
{
"name": "Alex",
"age": 25,
"role": "admin"
}
При активированном whitelist: true и
forbidNonWhitelisted: true поле role приведёт
к ошибке, поскольку оно не описано в DTO.
При обнаружении неразрешённых полей система выбрасывает исключение уровня валидации. В контексте серверных фреймворков это обычно преобразуется в HTTP-ошибку с кодом 400.
Сообщение об ошибке содержит информацию о наличии лишних свойств, что позволяет диагностировать проблему на стороне клиента.
Использование forbidNonWhitelisted повышает устойчивость
API к следующим классам проблем:
Особенно критично это в системах, где входной объект напрямую используется для создания или обновления сущностей в базе данных.
Для корректной работы строгой фильтрации обычно включается преобразование входящих данных в экземпляры классов. Это позволяет валидатору точно определять, какие поля принадлежат DTO, а какие являются лишними.
Без преобразования часть механизмов может работать некорректно, так как входной объект остаётся простым JSON и не имеет метаданных класса.
Несмотря на полезность строгого режима, он может приводить к нежелательным ситуациям:
В таких случаях включение forbidNonWhitelisted требует
строгого контроля версий и контрактов.
При работе с вложенными объектами правило применяется рекурсивно. Если DTO содержит вложенные классы, каждый уровень проходит проверку на наличие неизвестных полей.
Это означает, что даже корректный внешний объект может быть отклонён из-за лишних данных внутри вложенных структур.
Использование forbidNonWhitelisted фактически означает
переход от модели «гибкого JSON» к модели «контрактных структур». API
перестаёт быть tolerant к изменениям входных данных и требует строгого
соответствия схемам.
Такой подход часто используется в системах, где: