Проверка данных формы в Node.js с помощью экспресс-валидатора

Введение При создании приложений, особенно клиентских, обязательно выполнять проверку на стороне сервера. Причина в том, что нельзя полагаться только на ввод пользователя; поскольку эти входные данные иногда содержат поддельные / вредоносные данные. Проверка на стороне клиента - отличный способ отсеять большую часть входных данных, но вам все равно необходимо выполнить проверку на стороне сервера. Есть много способов проверить данные в Node.js, и в этой статье мы рассмотрим express-vali.

Вступление

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

Проверка на стороне клиента - отличный способ отсеять большую часть входных данных, но вам все равно необходимо выполнить проверку на стороне сервера.

Есть много способов проверить данные в Node.js, и в этой статье мы рассмотрим экспресс-валидатор . Экспресс-валидатор - это библиотека, которая обертывает validator.js и представляет его функции как набор промежуточного программного обеспечения.

Настройка проекта

В этом руководстве мы создадим демонстрационный внутренний сервер для имитации регистрации пользователя и входа в систему с помощью Node.js. Эти поля будут обеспечивать соблюдение определенных правил, и мы будем проверять полученные данные.

Обратите внимание, что мы не будем обрабатывать фактическую регистрацию пользователя и логику входа в систему, то есть сохранять данные пользователя и внедрять аутентификацию, поскольку это выходит за рамки данной статьи.

Для начала создадим папку проекта, перейдем в нее и инициализируем:

 # Create the project folder 
 $ mkdir express-validator-tut 
 
 # Navigate into the project folder 
 $ cd express-validator-tut 
 
 # Initialize project 
 $ yarn init -y 
 # OR 
 $ npm init -y 

Когда закончите, мы установим следующие зависимости, выполнив команду ниже:

 $ yarn add body-parser express express-validator 
 # OR 
 $ npm i body-parser express express-validator 

Посмотрим, что мы установили:

  • express: легкая структура веб-приложений для Node.js. Мы будем использовать это для обработки маршрутизации на нашем внутреннем сервере.
  • body-parser: ПО промежуточного слоя, которое поможет нам анализировать входящие запросы ( req.body пользователем данные) к объекту req.body.
  • экспресс-валидатор: библиотека, которую мы будем использовать для обработки входящей проверки ввода.

Наконец, мы создадим index.js каталоге нашего проекта для размещения стандартного кода для создания экземпляра приложения / сервера Express:

 // index.js 
 const express = require('express'); 
 const app = express(); 
 const bodyParser = require('body-parser'); 
 const port = 2022; 
 
 app.use(bodyParser.urlencoded({ extended: false })); 
 app.use(bodyParser.json()); 
 
 app.post('/register', (req, res) => {}); 
 
 app.listen(port); 
 console.log('See where it all happens at http://localhost:'+port); 

Теперь давайте запустим это приложение с помощью node :

 $ node index.js 

Если все пойдет хорошо, ваш терминал должен вывести что-то вроде:

шаблонное приглашение сервераexpressjs{.ezlazyload}

Стандартные правила валидации с экспресс-валидатором

В этом разделе мы узнаем, как добавлять простые правила проверки и очистки к входящим запросам. Во-первых, мы хотим проверить, является ли значение, введенное в поле электронной почты, действительным или нет. Затем мы хотим, чтобы пароль содержал не менее 6 символов.

Для начала давайте добавим пару функций промежуточного программного обеспечения к нашему маршруту /login

 // index.js 
 ... 
 const { body, validationResult } = require('express-validator'); 
 
 app.post('/login', 
 body('email').isEmail().normalizeEmail(), 
 body('password').isLength({ 
 min: 6 
 }), 
 (req, res) => { 
 const errors = validationResult(req); 
 
 if (!errors.isEmpty()) { 
 return res.status(400).json({ 
 success: false, 
 errors: errors.array() 
 }); 
 } 
 
 res.status(200).json({ 
 success: true, 
 message: 'Login successful', 
 }) 
 }); 
 ... 

В приведенном выше фрагменте мы используем два метода проверки:

  • isEmail() : эта функция валидатора проверяет, является ли входящая строка допустимым адресом электронной почты.
  • isLength() : этот валидатор проверяет, попадает ли длина строки в указанный диапазон. В нашем случае указанный диапазон составляет минимум 6 символов.

Вот некоторые из других методов, которые мы могли бы использовать:

  • isNumeric() - Проверяет, является ли ввод числовым
  • contains() - Проверяет, содержит ли ввод определенное значение
  • isBoolean() - Проверяет, является ли ввод логическим значением
  • isCurrency() - проверяет, отформатирован ли ввод в валюте.
  • isJSON() - Проверяет, является ли ввод JSON
  • isMobilePhone() - Проверяет, является ли введенный действительный номер мобильного телефона.
  • isPostalCode() - Проверяет, является ли введенный почтовый индекс действительным.
  • isBefore() и isAfter() - проверяет, находится ли дата до или после другой даты

Есть и другие, но они, вероятно, покрывают большую часть ваших потребностей в валидации.

Чтобы адреса электронной почты, предоставленные пользователем, не содержали шума и нарушений, мы добавим дезинфицирующее средство в наше поле электронной почты, как показано в приведенном выше фрагменте. Метод normalizeEmail() помогает преобразовать введенные электронные письма в стандартный утвержденный формат. Это означает, что если пользователь вводит, например, [email protected] , она будет канонизирована на [email protected] .

Validator.js предлагает некоторую гибкость , как этот вариант может быть переключена off или on но установлена on умолчанию. Существует множество вариантов нормализации, которые вы можете попробовать, если планируете нормализовать ввод. Если вы хотите узнать больше о других функциях валидаторов / дезинфицирующих средств, вы можете ознакомиться с официальной документацией Validator.js.

Давайте протестируем наш код, отправив запрос с неверным паролем и @googleemail.com , используя Postman или curl :

простая проверкаданных{.ezlazyload}

Пока что мы рассмотрели, как мы можем проверить входящие данные для образца конечной точки входа в систему. Теперь давайте переключимся на конечную точку регистрации и рассмотрим такие задачи, как настраиваемые правила проверки, сообщения об ошибках, проверка схемы и стандартизация сообщений проверки.

Пользовательские правила проверки и сообщения об ошибках с экспресс-валидатором

Для начала давайте создадим нашу конечную точку регистрации пользователей, добавив следующий фрагмент в наш файл index.js

 // index.js 
 ... 
 app.post('/register', (req, res) => { 
 // Validate incoming input 
 res.status(200).json({ 
 success: true, 
 message: 'Registration successful', 
 }); 
 }); 
 ... 

custom () Метод

Чтобы убедиться, что наши пользователи вводят уникальные имена пользователей во время регистрации, мы не можем использовать стандартные методы, заимствованные из методов Validator.js, поскольку нет метода для их проверки.

Для этого нам придется написать собственный валидатор, что можно сделать с помощью метода custom() Метод custom() принимает функцию, которая дополнительно может быть асинхронной. Если функция является асинхронной, вы захотите отклонить обещание в случае сбоя проверки и указать собственное сообщение. В противном случае вы можете создать исключение.

Начнем с отказа от обещания:

 // index.js 
 ... 
 app.post('/register', 
 body("username").custom(value => { 
 return User.find({ 
 username: value 
 }).then(user => { 
 if (user.length > 0) { 
 // Custom error message and reject 
 // the promise 
 return Promise.reject('Username already in use'); 
 } 
 }); 
 }), 
 (req, res) => { 
 // Validate incoming input 
 const errors = validationResult(req); 
 if (!errors.isEmpty()) { 
 return res.status(400).json({ 
 errors: errors.array() 
 }); 
 } 
 ... 
 }) 

В приведенном выше фрагменте кода мы вызываем метод find() в схеме Mongoose модели User, чтобы проверить, существует ли уже введенное клиентом имя пользователя в нашей базе данных.

Если он присутствует, мы отклоняем обещание с сообщением, которое хотим вернуть пользователю.

Хотя MongoDB автоматически обнаружит это, если поле имени пользователя было помечено как уникальное при указании схемы базы данных. Рекомендуется обработать это до того, как оно попадет в базу данных, чтобы наше приложение не завершилось преждевременно.

В качестве альтернативы вы можете создать исключение, чтобы указать недопустимый ввод:

 // index.js 
 ... 
 
 app.post('/register', 
 body("username").custom(value => { 
 return User.find({ 
 username: value 
 }).then(user => { 
 if (user.length > 0) { 
 throw ("Username is taken!"); //custom error message 
 } 
 }); 
 }), 
 ... 

withMessage () Метод

Второй способ реализовать настраиваемые сообщения об ошибках проверки - использовать withMessage() . Вы можете поместить несколько валидаторов, за которыми withMessage() чтобы указать сообщения об ошибках для каждой валидации:

 body("parameter") 
 .validator1() 
 .withMessage('Message 1') 
 .validator2() 
 .withMessage('Message 2') 

Давайте применим это с помощью реальных методов к нашему примеру:

 // index.js 
 
 ... 
 app.post('/register', 
 body("password").isStrongPassword({ 
 minLength: 8, 
 minLowercase: 1, 
 minUppercase: 1, 
 minNumbers: 1 
 }) 
 .withMessage("Password must be greater than 8 and contain at least one uppercase letter, one lowercase letter, and one number"), 
 (req, res) => { 
 // Validate incoming input 
 }) 
 ... 

Давайте сделаем еще один запрос с неверным паролем и уже используемым именем пользователя:

настраиваемые правила проверки и сообщения обошибках{.ezlazyload}

Проверка схемы с помощью экспресс-валидатора

Проверка схемы предлагает более чистый подход к проверке данных. Вместо того, чтобы вызывать множество функций, мы указываем правила проверки для каждого поля и передаем схему в одну функцию промежуточного программного обеспечения, называемую checkSchema() .

В приведенном ниже фрагменте мы будем создавать схему проверки для конечной точки регистрации пользователя:

 // index.js 
 ... 
 const {body, checkSchema, validationResult} = require('express-validator'); 
 const registrationSchema = { 
 username: { 
 custom: { 
 options: value => { 
 return User.find({ 
 username: value 
 }).then(user => { 
 if (user.length > 0) { 
 return Promise.reject('Username already in use') 
 } 
 }) 
 } 
 } 
 }, 
 gender: { 
 notEmpty: true, 
 errorMessage: "Gender field cannot be empty" 
 }, 
 password: { 
 isStrongPassword: { 
 minLength: 8, 
 minLowercase: 1, 
 minUppercase: 1, 
 minNumbers: 1 
 }, 
 errorMessage: "Password must be greater than 8 and contain at least one uppercase letter, one lowercase letter, and one number", 
 }, 
 phone: { 
 notEmpty: true, 
 errorMessage: "Phone number cannot be empty" 
 }, 
 email: { 
 normalizeEmail: true, 
 custom: { 
 options: value => { 
 return User.find({ 
 email: value 
 }).then(user => { 
 if (user.length > 0) { 
 return Promise.reject('Email address already taken') 
 } 
 }) 
 } 
 } 
 } 
 } 
 ... 

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

Теперь мы можем продолжить и использовать эту checkSchema() для проверки данных при регистрации:

 app.post('/signup', checkSchema(registrationSchema), (req, res) => { 
 // Validate incoming input 
 const errors = validationResult(req); 
 
 if (!errors.isEmpty()) { 
 return res.status(400).json({ 
 errors: errors.array() 
 }); 
 } 
 
 res.status(200).json({ 
 success: true, 
 message: 'Registration successful', 
 }); 
 }) 

Если вам нужно лишь небольшое количество проверок и вы хотите, чтобы это было просто, вы можете использовать методы. Если вам нужно выполнить огромное количество проверок, это будет более читабельно, если вы воспользуетесь проверкой схемы.

Стандартизация проверочных ответов с помощью экспресс-валидатора

express-validator позволяет стандартизировать ответы на ошибки валидации. Это означает, что вы можете создавать свои функции промежуточного программного обеспечения для выполнения проверок и обработки ошибок проверки.

Примером того, как это можно сделать, является создание функции validate() которая будет принимать все наши валидаторы и запускать их параллельно с помощью Promise.all() :

 // index.js 
 const validate = validations => { 
 return async (req, res, next) => { 
 await Promise.all(validations.map(validation => validation.run(req))); 
 
 const errors = validationResult(req); 
 if (errors.isEmpty()) { 
 return next(); 
 } 
 
 res.status(400).json({ 
 errors: errors.array() 
 }); 
 }; 
 }; 

Теперь наша функция проверки создана, и мы можем повторно использовать ее на нескольких маршрутах. Применим его к нашим маршрутам входа и регистрации:

 // index.js 
 ... 
 app.post('/login', validate([ 
 body('email').isEmail().normalizeEmail(), 
 body('password').isLength({ 
 min: 12 
 }) 
 ]), 
 (req, res) => { 
 // Process data 
 res.status(200).json({ 
 success: true, 
 message: 'Login successful', 
 }) 
 }); 
 
 app.post('/register', validate(checkSchema(registrationSchema)), (req, res) => { 
 // Process data 
 res.status(200).json({ 
 success: true, 
 message: 'Registration successful', 
 }); 
 }); 
 ... 

Как видно из приведенного выше фрагмента, использование специального промежуточного программного обеспечения для проверки, которое запускает все наши валидаторы и дезинфицирующие средства, не только дает нам повышение производительности с помощью Promise.all() , но и улучшает читаемость кода. Это окажется полезным, когда нам нужно проверить множество полей формы.

Заключение

В этой статье мы рассмотрели базовое и более продвинутое использование express-validator , отличной облегченной библиотеки, которая является оболочкой известной библиотеки validator.js

comments powered by Disqus