@IsIP

Декоратор @IsIP относится к группе валидаторов библиотеки Class-validator и предназначен для проверки строкового значения на соответствие формату IP-адреса. Он поддерживает как IPv4, так и IPv6, а также позволяет ограничивать допустимый тип адреса через параметры конфигурации.


Назначение и область применения

IP-адреса широко используются в сетевых приложениях, системах логирования, API-шлюзах, настройках доступа и телеметрии. Ошибки в формате IP могут приводить к:

  • некорректной маршрутизации запросов;
  • сбоям в системах авторизации по IP;
  • уязвимостям при отсутствии строгой проверки входных данных;
  • логическим ошибкам при обработке сетевых метаданных.

@IsIP обеспечивает структурную валидацию строки до уровня синтаксиса, исключая некорректные значения до попадания в бизнес-логику.


Базовый синтаксис

В простейшем варианте декоратор применяется без параметров:

import { IsIP } from 'class-validator';

class NetworkConfig {
  @IsIP()
  address: string;
}

В этом случае допускаются IPv4 и IPv6 адреса.


Валидация IPv4

IPv4 адрес состоит из четырёх октетов (0–255), разделённых точками.

Примеры валидных значений:

  • 192.168.0.1
  • 10.0.0.255
  • 127.0.0.1

Пример использования:

import { IsIP } from 'class-validator';

class ServerDto {
  @IsIP('4')
  host: string;
}

Здесь параметр '4' ограничивает проверку только IPv4 адресами.


Валидация IPv6

IPv6 представляет собой 128-битный адрес, записанный в шестнадцатеричном формате, разделённый двоеточиями.

Примеры:

  • ::1
  • 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • fe80::1ff:fe23:4567:890a

Пример ограничения:

import { IsIP } from 'class-validator';

class ServerDto {
  @IsIP('6')
  host: string;
}

Поддерживаемые режимы

Декоратор принимает необязательный параметр типа:

type IPVersion = '4' | '6' | 'both';

Значения параметра:

  • ‘4’ — только IPv4
  • ‘6’ — только IPv6
  • ‘both’ — оба формата (поведение по умолчанию)

Пример явного указания:

class ConnectionDto {
  @IsIP('both')
  clientIp: string;
}

Поведение при пустых и некорректных значениях

Пустая строка

Пустое значение не считается валидным IP:

''

Результат: ошибка валидации.


null и undefined

По умолчанию class-validator не валидирует undefined и null, если не используются дополнительные декораторы:

  • @IsOptional() — пропуск проверки при отсутствии значения
  • иначе значение считается некорректным

Пример:

import { IsIP, IsOptional } from 'class-validator';

class ProxyDto {
  @IsOptional()
  @IsIP('4')
  proxyIp?: string;
}

Совместное использование с другими валидаторами

Проверка обязательности поля

import { IsNotEmpty, IsIP } from 'class-validator';

class NodeDto {
  @IsNotEmpty()
  @IsIP('4')
  ip: string;
}

@IsNotEmpty() обеспечивает наличие значения, а @IsIP() — корректность формата.


Комбинация с IsString

import { IsString, IsIP } from 'class-validator';

class HostDto {
  @IsString()
  @IsIP('both')
  address: string;
}

Хотя IP-адрес всегда строка, явная проверка типа используется в строгих схемах DTO.


Особенности валидации IPv4

Class-validator учитывает специфику IPv4:

  • запрещены ведущие нули в октетах (в зависимости от режима парсинга);
  • каждый октет должен быть в диапазоне 0–255;
  • обязательны четыре части адреса.

Примеры некорректных значений:

  • 256.100.50.25
  • 192.168.1
  • 192.168.01.1 (в ряде случаев считается неоднозначным)
  • 999.999.999.999

Особенности валидации IPv6

IPv6 проверка включает:

  • корректность шестнадцатеричных символов;
  • допустимость сокращённой записи ::;
  • проверку длины адреса;
  • корректное количество сегментов.

Примеры некорректных значений:

  • 2001:::1 (двойное сокращение)
  • 2001:db8:::1
  • gggg::1 (недопустимые символы)

Поведение в NestJS DTO

В экосистеме NestJS декоратор используется в DTO-классах для автоматической валидации входящих данных:

import { IsIP } from 'class-validator';

export class CreateServerDto {
  @IsIP('4')
  gateway: string;
}

При включённом ValidationPipe любые некорректные значения приводят к выбросу ошибки BadRequestException.


Работа внутри pipeline валидации

Механизм проверки @IsIP включает несколько этапов:

  1. Получение значения свойства объекта.
  2. Проверка на строковый тип (или приведение в рамках трансформации).
  3. Передача значения в IP-валидатор.
  4. Разбор структуры строки по правилам IPv4/IPv6.
  5. Возврат результата true/false.
  6. Формирование списка ошибок при невалидности.

Производительность

Проверка IP-адресов имеет низкую вычислительную сложность:

  • O(n), где n — длина строки;
  • отсутствуют тяжёлые регулярные выражения в критическом смысле (используются оптимизированные проверки);
  • подходит для массовой валидации входящих запросов.

В высоконагруженных системах валидатор может применяться без заметного влияния на latency.


Типичные сценарии использования

API-шлюзы

Проверка IP клиента:

class RequestMetaDto {
  @IsIP('both')
  clientIp: string;
}

Конфигурация серверов

class DatabaseConfig {
  @IsIP('4')
  host: string;
}

Системы логирования

class LogEntryDto {
  @IsIP('both')
  sourceIp: string;
}

Ограничения

  • проверяет только синтаксис, но не принадлежность к сети или доступность адреса;
  • не определяет приватность или публичность IP;
  • не валидирует DNS-имена (для этого используются другие декораторы);
  • не выполняет сетевые запросы.

Отличия от @IsUrl и @IsFQDN

  • @IsIP — строго IP-адреса
  • @IsUrl — URL-адреса с протоколом и доменом
  • @IsFQDN — доменные имена

Пример различий:


Поведение при кастомных валидаторах

@IsIP может использоваться внутри пользовательских валидаторов:

import { ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';

@ValidatorConstraint({ name: 'customIpCheck', async: false })
export class CustomIpCheck implements ValidatorConstraintInterface {
  validate(value: string) {
    return typeof value === 'string' && value.startsWith('192.') && value.length > 7;
  }
}

Хотя подобные проверки не заменяют @IsIP, они могут дополнять его логикой бизнес-уровня.


Обработка ошибок

При нарушении формата IP возвращается стандартная ошибка:

{
  "constraints": {
    "isIP": "address must be an ip address"
  }
}

Сообщение может быть локализовано через механизмы i18n или переопределено через ValidationOptions.


Расширенная конфигурация через ValidationOptions

@IsIP('4', {
  message: 'Некорректный IPv4 адрес'
})
ip: string;

Возможности:

  • кастомизация текста ошибки;
  • добавление условий группировки;
  • интеграция с системой логирования ошибок.