Article Cover Image - Securing APIs: Express rate limit and slow down
贊助

保護 API:Express 速率限制和減速

閱讀時間 6 分鐘

速率限制和慢速機制有助於維持 Web 應用程式的穩定性、安全性和效能。這些控制可以防止系統過載,並提供一定程度的保護,抵禦暴力破解和分散式拒絕服務 (DDoS) 攻擊。速率限制還可以提高應用程式的可伸縮性,並透過維持服務質量和可靠性來增強使用者體驗。

內容分發網路 (CDN) 和網路級解決方案是保護專案免受這些問題影響的流行且便捷的方式,但您也可以直接在應用程式中實施控制和慢速邏輯。這種方法讓您可以更好地控制伺服器的行為,並在 CDN 或 DDoS 防護出現故障時提供額外的後備方案。此外,非惡意的指令碼或應用程式整合也可能由於 bug 或網路問題而出現故障。速率限制和慢速機制可以阻止程式過度執行操作,無意中消耗系統或網路資源。

在本文中,我們將建立一個 Express 應用程式,並整合速率限制和慢速邏輯,使其更具可伸縮性和安全性。保護應用程式的安全有許多方面,但透過使用本文介紹的方法,您應該能夠輕鬆地配置一種額外的方式來確保您的 Express 應用程式更具彈性和安全性。

在 Vultr 上設定 Express 應用

首先,按照我們上一篇文章中在 Vultr 上部署伺服器部分中的步驟部署伺服器。接下來,讓我們透過 SSH 訪問伺服器終端,併為我們的 Web 應用程式設定一個專案。

我們將使用 Nano 文字編輯器在伺服器上建立和編輯專案檔案。您可以查閱 快捷鍵備忘單以獲取使用 Nano 的幫助。我們還將使用 Uncomplicated Firewall (UFW) 來控制允許進出伺服器的流量。我們的 Express 應用使用埠 3000,因此我們可以透過 UFW 只允許透過此埠的入站流量。

  1. 建立一個專案目錄,並進入該目錄。

    bash
    mkdir express-api-security
    cd express-api-security
    
  2. 初始化一個 Node.js 專案。

    bash
    npm init -y
    
  3. 安裝 Express 依賴項。

    bash
    npm install express
    
  4. 為著陸頁建立一個新目錄,並進入該目錄。

    bash
    mkdir public
    cd public
    
  5. 建立一個 HTML 檔案。

    bash
    nano index.html
    
  6. 將以下程式碼複製並貼上到 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>
    
  7. 儲存並退出檔案。

  8. 退出 public 目錄,並建立一個 JavaScript 檔案。

    bash
    cd ..
    nano app.js
    
  9. 將以下程式碼複製並貼上到 app.js 檔案中。

    js
    const 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}`);
    });
    
  10. 允許入站連線到埠 3000

    bash
    ufw allow 3000
    
  11. 重新載入防火牆。

    bash
    ufw reload
    
  12. 執行 Node.js 應用程式。

    bash
    node app.js
    

如果您的應用程式正在執行,您應該會在控制檯中看到“Server is running on port 3000”的日誌,並且您可以透過伺服器 IP 和埠 3000 訪問該應用程式。

http://<server-ip>:3000

您可以根據需要多次重新載入網頁,重新載入速度不受影響,因為沒有應用速率限制和慢速機制。您可以透過按 Ctrl + C 來停止應用程式。

理解 Express 速率限制中介軟體

express-rate-limit 中介軟體用於控制對 Express 應用程式的入站請求速率。

  • windowMs:定義速率限制適用的時間(以毫秒為單位)。例如,windowMs: 15 * 60 * 1000 設定了一個 15 分鐘的時間視窗。
  • max:指定在時間視窗內允許來自單個 IP 地址的最大請求數。如果請求超過此定義的限制,則會觸發速率限制。

在 Express 應用程式中實現速率限制

在本節中,我們將把 express-rate-limit 中介軟體應用到 Express 應用程式。

  1. 安裝 express-rate-limit 依賴項。

    bash
    npm install express-rate-limit
    
  2. 開啟 express-api-security 目錄中的 app.js 檔案。

    bash
    nano app.js
    
  3. 新增中介軟體。您的 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}`);
    });
    
  4. 儲存並退出檔案。

  5. 使用 node app.js 執行應用程式。

讓我們看看我們在 app.js 中所做的更改。我們匯入 express-rate-limit,並建立一個名為 limiter 的常量速率限制器,將其配置為在 15 分鐘視窗內每個 IP 地址最多允許 5 個請求。

如果客戶端超過定義的限制,後續請求將收到 429 (Too Many Requests) 狀態碼,直到時間視窗重置。您可以使用 app.use(limiter) 來啟用中介軟體。

當您訪問應用程式 URL 時,請多次重新整理頁面。當您重新整理頁面 6 次時,您將看到一個瀏覽器錯誤螢幕,顯示“Too many requests, please try again later”。完成速率限制測試後,按 Ctrl + C 停止應用程式。

理解 Express 慢速中介軟體

express-slow-down 中介軟體會在響應請求時引入延遲。這種延遲有助於將入站請求分散到一段時間內,從而減少伺服器負載。與速率限制不同,它不會在超出限制時立即拒絕請求。

  • delayAfter:指定在此之後開始應用減速效果的請求數。例如,將 delayAfter: 1 設定為表示在第一個請求後應用減速。
  • delayMs:指定在超出 delayAfter 定義的限制後新增到每個請求的延遲(以毫秒為單位)。

將慢速機制整合到 Express 應用程式中

在本節中,我們將把 Express 慢速中介軟體應用到 Express 應用程式。

  1. 安裝 express-slow-down 依賴項。

    bash
    npm install express-slow-down
    
  2. 開啟 express-api-security 目錄中的 app.js 檔案。

    bash
    nano app.js
    
  3. 新增中介軟體。您的 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}`);
    });
    
  4. 儲存並退出檔案。

  5. 使用 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 的資訊。