摘要: 在本教程中,您将学习如何使用 express-validator 库来验证和清理输入数据。
当您的 Express 应用程序从外部来源(如用户输入)接收数据时,对输入数据进行验证和清理至关重要。
- 数据验证确保输入数据满足某些条件,例如类型、范围和格式。它验证输入数据是否有效。例如,您可以检查电子邮件地址是否具有有效的格式。
- 数据清理通过删除或转义有害字符来清理输入数据。它有助于防止恶意输入,例如代码注入。例如,您可以在将输入数据渲染到网页之前,从输入数据中删除 HTML 或脚本标记。
在 Express 应用程序中,您可以手动验证和清理输入数据,但此过程很耗时,需要更多努力。
为了提高效率,您可以使用第三方验证库。在本教程中,您将学习如何使用 express-validator 库 来验证和清理输入数据。
验证查询字符串
首先,创建一个简单的 Express 应用程序
import express from 'express';
const PORT = process.env.PORT || 3000;
const app = express();
app.get('/hi', (req, res) => res.send(`Hi, ${req.params.name}!`));
app.listen(PORT, () => console.log(`The server is listening on port ${PORT}`));
Code language: JavaScript (javascript)
该应用程序包含一个路由/hi
,它接受一个查询字符串name
。它将在 Web 浏览器上显示问候消息。
其次,通过在终端中运行以下npm
命令,在项目中安装express-validator
库
npm install express-validator
Code language: JavaScript (javascript)
第三,创建一个对以下端点的请求
http://localhost:3000/hi?name=John
Code language: JavaScript (javascript)
它将在 Web 浏览器上显示以下消息
Hi, John!
Code language: JavaScript (javascript)
但是,如果您在不传递name
查询字符串的情况下请求以下端点
http://localhost:3000/hi
Code language: JavaScript (javascript)
您将在屏幕上看到以下消息
Hi, undefined
Code language: JavaScript (javascript)
原因是在此示例中,req.query.name
为undefined
。
在最坏的情况下,如果查询字符串包含 JavaScript 代码,您可能会被重定向到恶意页面。例如
http://localhost:3000/hi?name=<script>window.location ='https://www.google.com';</script>
Code language: JavaScript (javascript)
在此示例中,我们注入将重定向到 google.com 的代码。在实际场景中,您可能会被重定向到恶意页面。这称为跨站点脚本 (XSS)。
跨站点脚本 (XSS) 是一种攻击,攻击者在受信任网站的代码中注入恶意可执行脚本。
要验证和清理name
查询字符串的值,可以使用express-validator
库。
从技术上讲,express-validator
库是一组中间件函数,用于验证和清理输入数据。
第四,使用express-validator
库中的函数验证name
查询字符串
import express from 'express';
import { query, validationResult, matchedData } from 'express-validator';
const PORT = process.env.PORT || 3000;
const app = express();
app.get('/hi', query('name').notEmpty().escape(), (req, res) => {
// validate data
const result = validationResult(req);
if (!result.isEmpty()) {
res.status(400).send({ errors: result.array() });
}
// sanitize data
const cleanedData = matchedData(req);
res.send(`Hi, ${cleanedData.name}!`);
});
app.listen(PORT, () => console.log(`The server is listening on port ${PORT}`));
Code language: JavaScript (javascript)
工作原理。
步骤 1. 从express-validator
库导入函数以处理验证
import { query, validationResult, matchedData } from 'express-validator';
Code language: JavaScript (javascript)
以下是导入函数的摘要
query()
函数是验证查询参数的中间件。validationResult()
函数收集对传入请求的验证和清理结果。matchedData()
函数提取验证和清理后的数据。
步骤 2. 验证 name 查询字符串
query('name').notEmpty().escape()
Code language: JavaScript (javascript)
在此语法中
notEmpty()
函数确保 name 查询字符串的值不为空。escape()
函数转义字段值以防止 XSS 攻击。
query()
、notEmpty()
和escape()
函数形成一个验证链。由于它们返回一个中间件函数,因此我们可以在app.get()
方法中使用它。
步骤 3. 使用validationResult()
函数获取验证结果
const result = validationResult(req);
if (!result.isEmpty()) {
res.status(400).send({ errors: result.array() });
}
Code language: JavaScript (javascript)
query()
函数不会自动报告验证错误。相反,它收集验证错误,然后使用validationResult()
函数进行验证。validationResult()
函数返回一个ValidationError
对象。
ValidationError
对象的isEmpty()
方法在没有发生验证错误时返回true
,否则返回false
。在代码中,我们返回一个包含验证错误的 JSON 响应,并使用 HTTP 状态码 400。
步骤 4. 获取清理后的数据
要获取清理后的数据,可以使用matchedData()
函数
const cleanedData = matchedData(req);
Code language: JavaScript (javascript)
步骤 5. 渲染清理后的数据
res.send(`Hi, ${cleanedData.name}!`);
Code language: JavaScript (javascript)
验证路由参数
要验证路由参数,可以使用express-validator
库中的param()
函数。
param()
函数允许您为路由参数指定验证规则。
以下示例显示了如何使用param()
函数验证 id 路由参数
app.get(
'/api/todos/:id',
param('id').isInt({ min: 1 }).withMessage('ID must be a positive integer'),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const id = req.params.id;
res.send(`Fetching record with ID: ${id}`);
}
);
Code language: JavaScript (javascript)
工作原理。
param('id')
指定用于验证的id
路由参数
isInt({ min: 1 })
确保id
参数为整数,且至少为 1。withMessage('ID 必须是正整数')
指定在验证失败时的自定义错误消息。
其余代码的工作方式与验证查询字符串相同。
验证请求主体
步骤 1. 要将请求处理为 JSON 对象,请注册名为express.json()
的内置中间件
app.use(express.json());
Code language: JavaScript (javascript)
这指示 Express 应用程序将主体解析为 JSON 对象,允许您通过req.body
属性访问它。
要访问 JSON 对象的字段,可以使用express-validator
库中的body()
函数。
步骤 2. 从express-validator
库导入body
函数
import {body, validationResult, matchedData} from 'express-validator';
Code language: JavaScript (javascript)
步骤 3. 验证请求主体中的title
和completed
字段
app.post('/api/todos',
[body('title').notEmpty().isString(), body('completed').isBoolean()],
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).send({ errors: errors.array() });
}
const record = matchedData(req);
res.send(record);
}
);
Code language: JavaScript (javascript)
在此示例中,我们将中间件数组传递给app.post()
函数。第一个中间件验证title
字段,第二个中间件验证请求主体中的completed
字段。
例如,如果您向/api/todos
端点发出 POST 请求,但在请求主体中没有指定title
和completed
字段,您将收到以下错误
{
"errors": [
{
"type": "field",
"msg": "Invalid value",
"path": "title",
"location": "body"
},
{
"type": "field",
"msg": "Invalid value",
"path": "title",
"location": "body"
},
{
"type": "field",
"msg": "Invalid value",
"path": "completed",
"location": "body"
}
]
}
Code language: JavaScript (javascript)
总结
- 使用
query()
函数验证查询字符串。 - 使用
param()
函数验证路由参数。 - 使用
body()
函数验证请求主体。