محدود کردن نرخ از یک سرویس در برابر بارگذاری بیش از حد محافظت می کند. بسته سرعت سرعت محدود و نحوه بهبود برنامه های شما را کشف کنید.
محدود کردن نرخ یک استراتژی است که می توانید از آن برای کنترل ترافیک در شبکه استفاده کنید. این تعداد درخواست هایی را که کاربر می تواند در یک بازه زمانی خاص انجام دهد محدود می کند.
الگوریتمهای محدودکننده نرخ مختلفی وجود دارد که هرکدام معاوضههای خاص خود را دارند. یک روش ساده و پرطرفدار ردیابی آدرس IP درخواستها و بررسی مدت زمان بین درخواستها است. اگر آدرس IP آن از تعداد درخواستهایی که محدودیت اجازه میدهد بیشتر باشد، سیستم میتواند درخواست را رد کند.
ایجاد این رویکرد برای محدود کردن نرخ در یک برنامه NodeJS-Express، تنها با چند مرحله آسان است.
مرحله 1: راه اندازی یک محیط توسعه
ابتدا باید یک برنامه Express ایجاد و مقداردهی اولیه کنید.
با ایجاد یک فهرست پروژه با اجرای:
mkdir express-app
سپس با اجرای:
cd express-app
سپس، npm، مدیر بسته گره را مقداردهی اولیه کنید و یک فایل package.json در برنامه خود با اجرای:
npm init -y
پرچم -y فایل package.json شما را با تمام تنظیمات پیش فرض ایجاد می کند.
در مرحله بعد، باید برخی از وابستگی ها را نصب کنید. وابستگی های مورد نیاز برای این آموزش عبارتند از:
- ExpressJS: ExpressJS یک چارچوب NodeJS است که مجموعه ای قوی از ویژگی ها را برای برنامه های کاربردی وب و موبایل ارائه می دهد. این فرآیند ساخت برنامه های کاربردی باطن با NodeJS را ساده می کند.
- محدودیت نرخ اکسپرس: محدودیت نرخ سریع یک میان افزار محدود کننده نرخ برای ExpressJS است. درخواستهای مکرر را به APIهای عمومی و/یا نقاط پایانی، مانند بازنشانی رمز عبور، ورود کاربران و غیره محدود میکند.
وابستگی های مورد نیاز را با اجرای:
npm install express express-rate-limit
مرحله 2: ایجاد یک برنامه اکسپرس
شما باید یک سرور اکسپرس اولیه ایجاد کنید که به درخواست هایی که برای برنامه شما ارسال می شود گوش دهد.
ابتدا یک فایل index.js در دایرکتوری ریشه پروژه خود ایجاد کنید. این فایل ورودی درخواست شما خواهد بود.
سپس کد زیر را به فایل index.js خود اضافه کنید:
// index.js
const express = require("express");
const app = express();
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log(`App running on port ${port}`);
});
این کد express را وارد کرده و با فراخوانی () express و ذخیره مقدار بازگشتی آن در متغیر app، یک برنامه Express ایجاد می کند. سپس با فراخوانی متد listen در شیء برنامه، به ترافیک پورت 3000 گوش می دهد.
مرحله 3: ایجاد Route Handlers
در مرحله بعد، چند کنترل کننده مسیر ایجاد کنید که بتوانید راه حل محدودکننده نرخ را روی آنها پیاده سازی کنید.
ابتدا با اجرای:
mkdir routes
یک فایل routes.js در داخل پوشه routes خود ایجاد کنید و کد زیر را اضافه کنید:
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
res.send({ message: "Hello, this is a GET request" });
});
router.post("/add-demo", (req, res) => {
res.status(201).send({ message: "Resource created successfully" });
});
router.put("/update-demo", (req, res) => {
res.status(201).send({ message: "Resource updated sucessfully" });
});
module.exports = router;
این کد express را وارد می کند، متد Router را در express فراخوانی می کند و مقدار را در یک متغیر، روتر ذخیره می کند. روش Router به شما امکان می دهد تا کنترلرهای مسیر ماژولار و قابل نصب را ایجاد کنید. میتوانید برای درخواست GET به «/»، یک درخواست POST به «/add-demo»، و یک درخواست PUT برای «/update-demo»، کنترلکنندههای مسیر ایجاد کنید. در نهایت، متغیر روتر را صادر کنید.
سپس، متغیر روتر را در فایل index.js خود وارد کنید:
// index.js
const routes = require("./routes/routes");
سپس، از آن به عنوان میان افزار در فایل index.js خود استفاده کنید:
// index.js
app.use(routes);
حتما بلوک کد را در بالا قبل از قرار دهید
app. listen
زنگ زدن.
مرحله 4: اجرای محدودیت نرخ
ابتدا با اجرای:
mkdir middleware
سپس یک فایل به نام “rate-limiter.js” در دایرکتوری میان افزار ایجاد کنید. کد زیر را به این فایل اضافه کنید:
// rate-limiter.js
const rateLimiter = require("express-rate-limit");
const limiter = rateLimiter({
max: 5,
windowMS: 10000, // 10 seconds
message: "You can't make any more requests at the moment. Try again later",
});
module.exports = limiter
تابع rateLimiter یک شی پیکربندی را با شرایط محدود کردن تعداد درخواست ها می گیرد.
ویژگی های موجود در شی پیکربندی بالا عبارتند از:
- max: این ویژگی همیشه باید یک عدد یا تابعی باشد که یک عدد را برمی گرداند. این نشان دهنده حداکثر تعداد درخواست هایی است که یک کاربر می تواند در یک بازه زمانی مشخص انجام دهد. اگر این ویژگی در شیء پیکربندی تنظیم نشده باشد، به طور پیش فرض 5 است.
- windowsMS: این ویژگی همیشه باید یک عدد باشد. این نشان دهنده بازه زمانی است که در آن چندین درخواست در میلی ثانیه مجاز است. اگر این ویژگی در شیء پیکربندی تنظیم نشده باشد، به طور پیش فرض روی 60000 میلی ثانیه (یک دقیقه) تنظیم می شود.
- message: این ویژگی می تواند یک رشته، یک شی JSON یا هر مقدار دیگری باشد که توسط متد express.send پشتیبانی می شود. اگر این ویژگی در شیء پیکربندی تنظیم نشده باشد، به طور پیشفرض روی «درخواستهای زیاد» تنظیم میشود. لطفاً بعداً دوباره امتحان کنید.»
سپس این تابع درخواست های مکرر به برنامه شما را بررسی می کند. اگر کاربر از حد مجاز (حداکثر، 5) در بازه زمانی (windowMS، 10s) فراتر رود، درخواست را مسدود می کند. همچنین یک خطای «درخواستهای خیلی زیاد» با کد وضعیت ۴۲۹ ایجاد میکند.
در نهایت تابع محدود کننده را در فایل index.js خود وارد کرده و آن را به عنوان میان افزار جهانی در برنامه خود اعمال کنید. این کار را با قرار دادن app.use(Limiter) در بالای میان افزار مسیرها انجام دهید. این راه حل محدود کننده نرخ را برای همه مسیرهای برنامه شما اعمال می کند.
app.use(limiter);
مسیرهای خاص محدود کننده نرخ
همچنین می توانید محدودیت نرخ را برای مسیرهای خاص اعمال کنید. شما می توانید آنها را به طور جداگانه پیکربندی کنید تا درخواست های ارائه شده در بازه زمانی متفاوت را رد کنند، پیام دیگری را نمایش دهند و غیره.
به عنوان مثال، فرض کنید در حال پیاده سازی یک مسیر ورود به سیستم کاربر در برنامه خود هستید. ممکن است لازم باشد یک پیکربندی محدود کننده نرخ برای مسیر ورود به سیستم اضافه کنید که با پیکربندی استفاده شده توسط مسیرهای دیگر متفاوت است.
ابتدا باید محدود کننده را به عنوان یک میان افزار در سطح برنامه حذف کنید و آن را اعمال کنید زیرا هیچ سیستم فیلتر میان افزار داخلی در ExpressJS وجود ندارد. بنابراین حتی اگر راه حل محدود کننده نرخ خاصی را به یک مسیر اضافه کنید، میان افزار جهانی همچنان در آن مسیر اجرا می شود.
در مرحله بعد، یک پیکربندی محدود کننده نرخ جدید در فایل rate-limiter.js خود ایجاد کنید و آن را صادر کنید.
const signInLimiter = rateLimiter({
max: 3,
windowMS: 10000, //10 seconds
message: "Too many sign-in attempts. Try again later."
})
module.exports = {
limiter,
signInLimiter
}
شیء پیکربندی signInLimiter دارای تعداد حداکثر درخواستها و پیام خطای متفاوتی از محدودکننده نرخ عمومی است.
در نهایت، فایل router.js خود را با بلوک کد زیر به روز کنید:
// router.js
const express = require("express");
const router = express.Router();
const {limiter, signInLimiter} = require("../middleware/rate-limiter")
router.get("/sign-in", signInLimiter, (req, res, next) => {
res.send({ message: "Hello, this is a GET request" });
});
router.use(limiter)
router.post("/post", (req, res) => {
res.status(201).send({ message: "Resource created successfully" });
});
router.put("/put", (req, res) => {
res.status(201).send({ message: "Resource updated sucessfully" });
});
module.exports = router;
در بلوک کد بالا، limiter و signInLimiter را وارد کردید. سپس signInLimiter را به عنوان یک محدود کننده نرخ خاص در مسیر “/sign-in” اعمال کردید.
در نهایت، با قرار دادن router.use(limiter) بالاتر از بقیه مسیرها، محدود کننده را به عنوان محدود کننده نرخ برای بقیه مسیرها اعمال کردید.
اهمیت محدود کردن نرخ
محدود کردن نرخ فشار روی سرور وب شما را با اجتناب از پردازش درخواست های بیش از حد به طور همزمان کاهش می دهد. فعالیت ربات ها را کاهش می دهد، از شما در برابر حملات انکار سرویس (DoS) محافظت می کند و از حملات brute-force جلوگیری می کند.