
API 安全:Express 速率限制和延迟
速率限制和延迟机制有助于维护 Web 应用程序的稳定性、安全性和性能。这些控制措施可以防止系统过载,并提供一定程度的保护,防止暴力攻击和分布式拒绝服务 (DDoS) 攻击。速率限制还可以提高应用程序的可扩展性,并通过维护服务质量和可靠性来增强用户体验。
内容分发网络 (CDN) 和网络级解决方案是保护项目免受这些问题的流行且便捷的方式,但您也可以直接在应用程序中实施控制和延迟逻辑。这种方法使您能够更好地控制服务器的行为,并在 CDN 或 DDoS 防护失败时提供额外的后备。此外,由于错误或网络问题,并非恶意脚本或应用程序集成可能会出现故障。速率限制和延迟机制可以阻止程序过度执行操作,并无意中使用系统或网络资源。
在本文中,我们将创建一个 Express 应用程序,并结合速率限制和延迟逻辑,使其更具可扩展性和安全性。保护应用程序有很多方面,但通过使用本文中描述的方法,您应该能够轻松地配置另一种方法,确保您的 Express 应用程序更具弹性和安全性。
在 Vultr 上设置 Express 应用程序
首先,按照我们在上一篇文章中在 Vultr 上部署服务器部分中的步骤部署服务器。接下来,让我们继续通过 SSH 访问服务器终端,并为我们的 Web 应用程序设置一个项目。
我们将使用Nano 文本编辑器在服务器上创建和编辑项目文件。您可以查看快捷方式备忘单,了解使用 Nano 的帮助。我们还将使用简单防火墙 (UFW) 来控制允许进出服务器的流量。我们的 Express 应用程序使用端口3000
,因此我们可以使用 UFW 只允许通过此端口的传入流量。
- 创建一个项目目录,并导航到该目录。bash
mkdir express-api-security cd express-api-security
- 初始化一个 Node.js 项目。bash
npm init -y
- 安装 Express 依赖项。bash
npm install express
- 为登录页面创建另一个目录,并导航到该目录。bash
mkdir public cd public
- 创建一个 HTML 文件。bash
nano index.html
- 将下面的代码复制并粘贴到
index.html
文件中。html<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Express Rate Limit & Slow Down</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; } .container { text-align: center; } h1 { color: #333; } p { color: #666; } </style> </head> <body> <div class="container"> <h1>Express Rate Limit & Slow Down Applied</h1> <p>Rate limiting and speed limiting are applied to this page.</p> </div> </body> </html>
- 保存并退出文件。
- 退出 public 目录,并创建一个 JavaScript 文件。bash
cd .. nano app.js
- 将下面的代码复制并粘贴到
app.js
文件中。jsconst express = require("express"); const app = express(); const port = 3000; app.use(express.static("public")); app.get("/", (req, res) => { res.sendFile(__dirname + "/public/index.html"); }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
- 允许传入端口
3000
的连接。bashufw allow 3000
- 重新加载防火墙。bash
ufw reload
- 运行 Node.js 应用程序。bash
node app.js
如果您的应用程序正在运行,您应该会看到“服务器正在端口 3000 上运行”日志记录到控制台中,并且您可以在服务器 IP 和端口3000
上访问该应用程序。
http://<server-ip>:3000
您可以根据需要重新加载网页,重新加载速度不会受到影响,因为没有应用速率限制和延迟机制。您可以通过按Ctrl + C停止应用程序。
了解 Express 速率限制中间件
express-rate-limit 中间件用于控制传入 Express 应用程序的请求速率。
windowMs
:定义速率限制适用的时间(以毫秒为单位)。例如,windowMs: 15 * 60 * 1000
设置一个 15 分钟的窗口。-
max
:指定在时间窗口内单个 IP 地址允许的最大请求数。如果请求超过此定义的限制,则将触发速率限制。
在 Express 应用程序中实施速率限制
在本节中,我们将向 Express 应用程序应用express-rate-limit 中间件。
- 安装
express-rate-limit
依赖项。bashnpm install express-rate-limit
- 在
express-api-security
目录中打开app.js
文件。bashnano app.js
- 添加中间件。您的 JavaScript 文件应如下所示:js
const express = require("express"); const rateLimit = require("express-rate-limit"); const app = express(); const port = 3000; const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5, }); app.use(limiter); app.use(express.static("public")); app.get("/", (req, res) => { res.sendFile(__dirname + "/public/index.html"); }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
- 保存并退出文件。
- 使用
node app.js
运行应用程序。
让我们看看我们在app.js
中所做的更改。我们正在导入express-rate-limit
,并将速率限制器创建为一个常量limiter
,并将其配置为在 15 分钟的窗口内每个 IP 地址最多允许 5 个请求。
如果客户端超过了定义的限制,后续请求将收到429 (太多请求) 状态代码,直到时间窗口重置。您可以使用app.use(limiter)
启用中间件。
当您访问应用程序 URL 时,刷新页面几次。当您刷新页面 6 次时,您将看到一个浏览器错误屏幕,显示“太多请求,请稍后再试”。完成速率限制测试后,通过按Ctrl + C停止应用程序。
了解 Express 延迟中间件
express-slow-down 中间件在响应请求时引入延迟。这种延迟有助于将传入请求分散在时间上,从而减少服务器的负载。与速率限制不同,它不会在超过限制时立即拒绝请求。
-
delayAfter
:指定执行延迟效果的请求数量。例如,设置delayAfter: 1
意味着延迟在第一个请求后应用。 delayMs
:指定在超过delayAfter
定义的限制后,每个请求添加的延迟(以毫秒为单位)。
在 Express 应用程序中实施延迟机制
在本节中,我们将向 Express 应用程序应用 Express 延迟中间件。
- 安装
express-slow-down
依赖项。bashnpm install express-slow-down
- 在
express-api-security
目录中打开app.js
文件。bashnano app.js
- 添加中间件。您的 JavaScript 文件应如下所示:js
const express = require("express"); const rateLimit = require("express-rate-limit"); const slowDown = require("express-slow-down"); const app = express(); const port = 3000; const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5, }); const speedLimiter = slowDown({ windowMs: 15 * 60 * 1000, delayAfter: 1, delayMs: () => 2000, }); app.use(speedLimiter); app.use(limiter); app.use(express.static("public")); app.get("/", (req, res) => { res.sendFile(__dirname + "/public/index.html"); }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
- 保存并退出文件。
- 使用
node app.js
运行应用程序。
我们在app.js
中做了与之前速率限制类似的更改。我们正在导入express-slow-down
,并将速度限制中间件创建为一个常量speedLimiter
。我们添加的配置在 1 个请求后减慢请求速率,并在 15 分钟的窗口内向每个后续请求添加 2000 毫秒(2 秒)的延迟。同样,您可以使用app.use(speedLimiter)
应用中间件。
当您访问应用程序 URL 时,尝试反复刷新页面。您会看到每次刷新页面时加载页面的时间都会增加。这是为了说明目的而过度使用延迟,因此您可以在实际应用程序中在更多请求之后启用速度限制。好处是,这可以根据应用程序的实际使用情况进行配置。
实际应用和示例
让我们看看速率限制和延迟如何在实际应用中使用。以下列举了两个常见的用例
- 社交媒体平台提供 API,允许开发人员访问其数据。但是,为了防止滥用并确保公平使用,这些平台会集成速率限制。
- API 端点具有定义的速率限制,指定用户在特定时间段内可以发出的请求数量。
- 他们还集成了延迟机制,以防止突然的请求爆发。
- 电子商务网站在节假日会经历流量高峰。为了防止服务器过载,确保顺利的结账流程,并防止欺诈,这些平台会在结账和订单处理工作流程中集成速率限制和延迟机制。
- 结账和订单处理端点受速率限制,以限制在特定时间段内发出的请求数量,例如将商品添加到购物车或提交订单。
- 超过初始速率限制后,其他请求可能会受到延迟,确保服务器能够处理传入订单,而不会因流量突然激增而不堪重负。
结论
在本文中,我们创建了一个 Express 应用程序,并学习了如何包含速率限制和延迟机制。通过学习如何在您的项目中整合和配置这些功能,您将能够创建可扩展的服务器端 Node.js 应用程序,这些应用程序具有更强大的请求处理功能,以实现更好的安全性和弹性。
这是一篇由 Vultr 赞助的文章。Vultr 是全球最大的私营云计算平台。Vultr 是开发人员的宠儿,已向 185 个国家/地区的 150 多万客户提供了灵活、可扩展、全球化的云计算、云 GPU、裸机和云存储解决方案。了解更多关于Vultr的信息。