express.js
This tutorial requires prior knowledge of using the expressjs framework
本教程需要使用expressjs框架的先验知识
为什么我们需要服务器端验证? (Why do we need server-side validation?)
- Your client side validation is not enough and it may be subverted 您的客户端验证不够,可能会被颠覆
More prone to Man in middle attacks, and the server should never trust the client-side
- A user can turn off client-side JavaScript validation and manipulate the data 用户可以关闭客户端JavaScript验证并处理数据
If you have been building web applications using an Express framework or any other Node.js framework, validation plays a crucial role in any web app which requires you to validate the request body
param
query
.
如果您一直在使用Express框架或任何其他Node.js框架构建Web应用程序,则验证在任何需要您验证请求body
param
query
Web应用程序中都起着至关重要的作用。
Writing your own middleware function can be cumbersome if
如果您自己编写中间件功能,可能会很麻烦
- you want to move fast while maintaining the quality of code or 您想要在保持代码质量的同时快速移动或
you want to avoid using
if (req.body.head)
orif (req.params.isCool)
in your main controller function where you define business logic您要避免在定义业务逻辑的主控制器函数中使用
if ( req .body.head)
或if ( req .params.isCool)
In this tutorial, you’ll learn how to validate input in an Express.js app using an open source and popular module called express-validator.
在本教程中,您将学习如何使用开源的流行模块express-validator验证 Express.js应用程序中的输入。
快速验证器简介 (Introduction to express-validator)
The definition on Github says:
Github上的定义说:
express-validator is a set of express.js middlewares that wraps validator.js validator and sanitizer functions.
express-validator是一组express.js中间件,其中包装了validator.js验证器和消毒器功能。
The module implements five important API’s:
该模块实现了五个重要的API:
- Check API 检查API
- Filter API 筛选器API
- Sanitization chain API 消毒链API
- Validation chain API 验证链API
- Validation Result API 验证结果API
Let's take a look at a basic user route
without any validation module to create a user: /route/user.js
让我们看一下没有任何验证模块即可创建用户的基本用户route
: /route/user.js
/**
* @api {post} /api/user Create user
* @apiName Create new user
* @apiPermission admin
* @apiGroup User
*
* @apiParam {String} [userName] username
* @apiParam {String} [email] Email
* @apiParam {String} [phone] Phone number
* @apiParam {String} [status] Status
*
* @apiSuccess (200) {Object} mixed `User` object
*/
router.post('/', userController.createUser)
Now in user controller /controllers/user.js
现在在用户控制器/controllers/user.js
const User = require('./models/user')
exports.createUser = (req, res, next) => {
/** Here you need to validate user input.
Let's say only Name and email are required field
*/
const { userName, email, phone, status } = req.body
if (userName && email && isValidEmail(email)) {
// isValidEmail is some custom email function to validate email which you might need write on your own or use npm module
User.create({
userName,
email,
phone,
status,
})
.then(user => res.json(user))
.catch(next)
}
}
The above code is just a basic example of validating fields on your own.
上面的代码只是一个自己验证字段的基本示例。
You can handle some validations in your user model using Mongoose. For best practices, we want to make sure validation happens before business logic.
您可以使用Mongoose在用户模型中处理一些验证。 对于最佳实践,我们希望确保在业务逻辑之前进行验证。
express-validator will take care of all these validations and the sanitization of inputs as well.
express-validator将负责所有这些验证以及输入的清理 。
安装 (Installation)
npm install --save express-validator
Include module in your main server.js
file:
在您的主要server.js
文件中包含模块 :
const express = require('express')
const bodyParser = require('body-parser')
const expressValidator = require('express-validator')
const app = express()
const router = express.Router()
app.use(bodyParser.json())
app.use(expressValidator())
app.use('/api', router)
Now using express-validator, your /routes/user.js
will be like this:
现在使用express-validator ,您的/routes/user.js
将如下所示:
router.post(
'/',
userController.validate('createUser'),
userController.createUser,
)
Here userController.validate
is a middleware function which is explained below. It accepts the method
name for which the validation will be used.
这里的userController.validate
是一个中间件函数,下面将对其进行说明。 它接受将用于验证的method
名称。
Let’s create a middleware function validate()
in our/controllers/user.js
:
让我们在/controllers/user.js
创建一个中间件函数validate()
:
const { body } = require('express-validator/check')
exports.validate = (method) => {
switch (method) {
case 'createUser': {
return [
body('userName', 'userName doesn't exists').exists(),
body('email', 'Invalid email').exists().isEmail(),
body('phone').optional().isInt(),
body('status').optional().isIn(['enabled', 'disabled'])
]
}
}
}
Please refer to this article to know more about function definition and its use.
请参考本文以了解有关函数定义及其使用的更多信息。
The body
function will only validate req.body
and takes two arguments. First is the property name
. Second is your custom message
that will be shown if validation fails. If you don’t provide a custom message, then the default message will be used.
body
函数将仅验证req.body
并接受两个参数。 首先是property name
。 其次是您的自定义message
,如果验证失败,将显示该message
。 如果您不提供自定义消息,则将使用默认消息。
As you can see, for a required
field we are using the .exists()
method. We are using .optional()
for an optional
field. Similarly isEmail()
isInt()
is used to validate email
and integer
.
如您所见,对于required
字段,我们使用.exists()
方法。 我们将.optional()
用于optional
字段。 同样, isEmail()
isInt()
用于验证email
和integer
。
If you want an input field to include only certain values, then you can use .isIn([])
. This takes an array
of values, and if you receive values other than the above, then an error will be thrown.
如果希望输入字段仅包含某些值,则可以使用.isIn([])
。 这需要一个值array
,如果您收到的不是上述值,则将引发错误。
For example, the status field in the above code snippet can only have an enabled
or disabled
value. If you provide any value other than that, an error will be thrown.
例如,以上代码片段中的status字段只能具有enabled
或disabled
值。 如果提供其他值,则将引发错误。
In /controllers/user.js
let’s write acreateUser
function where you can write business logic. It will be called after validate()
with the result of the validations.
在/controllers/user.js
让我们编写一个createUser
函数,您可以在其中编写业务逻辑。 将在validate()
之后调用 验证的结果。
const { validationResult } = require('express-validator/check');
exports.createUser = async (req, res, next) => {
try {
const errors = validationResult(req); // Finds the validation errors in this request and wraps them in an object with handy functions
if (!errors.isEmpty()) {
res.status(422).json({ errors: errors.array() });
return;
}
const { userName, email, phone, status } = req.body
const user = await User.create({
userName,
email,
phone,
status,
})
res.json(user)
} catch(err) {
return next(err)
}
}
如果您想知道validationResult(req)是什么? (If you are wondering what is validationResult(req)?)
This function finds the validation errors in this request and wraps them in an object with handy functions
此函数 在此请求中查找验证错误,并将其包装在具有方便功能的对象中
Now whenever request includes invalid body params or userName
field is missing in req.body
, your server will respond like this:
现在,只要请求中包含无效的正文参数或req.body
缺少userName
字段,您的服务器就会像这样响应:
{
"errors": [{
"location": "body",
"msg": "userName is required",
"param": "userName"
}]
}
So if userName
or email
failed to satisfy the validation then each error returned by .array()
method has the following format by default:
因此,如果userName
或email
无法满足验证要求,则.array()
方法返回的每个错误默认情况下都具有以下格式:
{
"msg": "The error message",
"param": "param name",
"value": "param value",
// Location of the param that generated this error.
// It's either body, query, params, cookies or headers.
"location": "body",
// nestedErrors only exist when using the oneOf function
"nestedErrors": [{ ... }]
}
As you can see, this module really helps us take care of most of the validations on its own. It maintains code quality as well, and focuses mainly on business logic.
如您所见,此模块确实可以帮助我们独自完成大多数验证。 它还保持代码质量,并且主要关注业务逻辑。
This was the introduction to input validation using the express-validator module and check out how to validate an array of the item and make your own custom validation in Part 2 of this series.
这是使用express-validator模块进行输入验证的简介,并在本系列的第2部分中介绍了如何验证商品的数组以及进行自己的自定义验证。
I have tried my best and hope I covered enough to explain it in detail so that you can get started.
我已尽力而为,并希望我能进行足够的详细介绍,以便您开始使用。
If you encounter any problems, feel free to get in touch or comment below.I would be happy to help :)
如果您遇到任何问题,请随时与我们联系或在下面发表评论。 我很乐意为您提供帮助:)
Follow Shailesh Shekhawat to get notified whenever I publish a new post.
每当我发布新帖子时,请关注Shailesh Shekhawat以获得通知。
Don’t hesitate to clap if you considered this a worthwhile read!
如果您认为这值得一读,请随时鼓掌!
Originally published at 101node.io on September 2, 2018.
最初于2018年9月2日发布在101node.io 。
express.js