Валидация входных данных в Node.js является одним из ключевых этапов построения устойчивых серверных приложений. Любой ввод извне — тело HTTP-запроса, параметры строки запроса, заголовки или данные из внешних API — рассматривается как потенциально недоверенный. Без строгой проверки такие данные становятся источником уязвимостей: SQL-инъекций, XSS, переполнений логики приложения, неконсистентного состояния бизнес-объектов.
В серверных приложениях на Node.js валидация выполняет несколько функций одновременно:
В архитектурно зрелых приложениях валидация располагается на уровне промежуточного слоя (middleware), до попадания данных в бизнес-логику.
В экосистеме Node.js применяются три основных подхода:
Использование обычных JavaScript-условий:
function validateUser(data) {
if (!data.email || typeof data.email !== 'string') {
throw new Error('Invalid email');
}
if (data.password.length < 8) {
throw new Error('Password too short');
}
}
Такой подход гибкий, но плохо масштабируется и приводит к дублированию логики.
Использование библиотек, описывающих схему данных (например, Joi, Zod). В этом случае структура данных формализуется декларативно.
К этой категории относится validator.js — набор функций для проверки и санитизации строковых значений.
validator.js представляет собой набор функций для проверки строковых данных. Она не навязывает структуру объектов и не реализует схемы, а работает на уровне отдельных значений.
Установка:
npm install validator
Основная особенность — ориентация исключительно на строки. Любые входные данные предварительно приводятся к строковому виду.
const validator = require('validator');
validator.isEmail('test@example.com'); // true
validator.isEmail('invalid-email'); // false
Функция строго проверяет соответствие RFC-формату email-адресов.
validator.isLength('Hello', { min: 2, max: 10 }); // true
validator.isLength('A', { min: 2 }); // false
Позволяет задавать минимальные и максимальные границы.
validator.isInt('42'); // true
validator.isInt('3.14'); // false
validator.isFloat('3.14'); // true
Важно учитывать, что входные значения интерпретируются как строки.
validator.isURL('https://example.com'); // true
validator.isURL('ftp://site'); // true (по настройкам)
Можно задавать строгие параметры протоколов:
validator.isURL('https://example.com', {
protocols: ['https'],
require_protocol: true
});
Помимо проверки, библиотека предоставляет методы очистки входных данных.
validator.normalizeEmail('Test@Example.com');
// test@example.com
Снижает вариативность хранения данных.
validator.escape('<script>alert("x")</script>');
// <script>alert("x")</script>
Используется для защиты от XSS при выводе данных.
validator.blacklist('abc123', 'a-z'); // 123
Позволяет удалять символы по маске.
В реальных приложениях validator.js часто используется внутри middleware.
const validator = require('validator');
function validateRegistration(req, res, next) {
const { email, password } = req.body;
const errors = [];
if (!validator.isEmail(email || '')) {
errors.push('Некорректный email');
}
if (!validator.isLength(password || '', { min: 8 })) {
errors.push('Пароль слишком короткий');
}
if (errors.length > 0) {
return res.status(400).json({ errors });
}
next();
}
Такой слой отделяет проверку данных от бизнес-логики контроллеров.
Библиотека предполагает композицию функций:
const username = 'User_123';
const isValid =
validator.isLength(username, { min: 3, max: 20 }) &&
validator.isAlphanumeric(username.replace('_', ''));
Комбинации позволяют строить гибкие правила без схем.
Ключевое ограничение — работа только со строками. Это требует явного приведения типов:
validator.isInt(String(10)); // true
При работе с JSON-запросами это особенно важно, так как числовые значения могут приходить в различных форматах.
Основные проблемы при использовании:
'')null и
undefinedПример корректного подхода:
const value = req.body.age;
if (!validator.isInt(value ? String(value) : '')) {
throw new Error('Invalid age');
}
validator.js оптимизирован для массовых проверок строк, но не предназначен для сложной валидации объектов. При больших объёмах данных накладные расходы минимальны, однако архитектурно библиотека не заменяет полноценные схемные валидаторы.
Основные ограничения:
В распределённых системах validator.js часто применяется на уровне API Gateway или входных адаптеров. Его роль — быстрый фильтр некорректных запросов до передачи в внутренние сервисы.
Типичный поток:
Такой подход снижает связанность компонентов и повышает устойчивость системы к некорректным входным данным.
Структурирование ошибок важно для предсказуемости API:
const errors = {
email: 'invalid format',
password: 'too short'
};
или массивный формат:
[
{ field: 'email', message: 'invalid format' },
{ field: 'password', message: 'too short' }
]
Выбор структуры зависит от контрактов API и клиентской стороны.
Хорошо масштабируемый подход — вынесение правил в отдельные модули:
const validator = require('validator');
const rules = {
email: (v) => validator.isEmail(v || ''),
password: (v) => validator.isLength(v || '', { min: 8 })
};
Это упрощает поддержку и повторное использование.
В реальных проектах validator.js часто используется совместно с:
Такое сочетание формирует многоуровневую защиту входных данных, где каждый слой решает свою задачу без дублирования ответственности.