تنفيذ تحديد معدل طلبات API
حماية واجهات برمجة التطبيقات من سوء الاستخدام باستخدام تحديد معدل الطلبات الفعّال.
خوارزميات تحديد المعدل
- النافذة الثابتة (Fixed Window): بسيطة، لكنها تسمح بطفرات عند حدود النافذة
- النافذة المنزلقة (Sliding Window): توزيع أكثر سلاسة للطلبات
- دلو الرموز (Token Bucket): يسمح بطفرات محكومة
- الدلو المتسرب (Leaky Bucket): معدل إخراج ثابت
تحديد المعدل في Laravel
// app/Providers/RouteServiceProvider.php
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
// Different limits for different endpoints
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->isPremium()
? Limit::none()
: Limit::perHour(10)->by($request->user()->id);
});
التنفيذ باستخدام Redis
const Redis = require('ioredis');
const redis = new Redis();
async function rateLimit(key, limit, windowSec) {
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, windowSec);
}
if (current > limit) {
const ttl = await redis.ttl(key);
throw new RateLimitError(`Rate limit exceeded. Retry after ${ttl}s`);
}
return { remaining: limit - current, reset: windowSec };
}
// Middleware
app.use(async (req, res, next) => {
try {
const key = `rate:${req.ip}`;
const { remaining, reset } = await rateLimit(key, 100, 60);
res.set('X-RateLimit-Remaining', remaining);
res.set('X-RateLimit-Reset', reset);
next();
} catch (error) {
res.status(429).json({ error: error.message });
}
});
ترويسات الاستجابة
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1640000000
Retry-After: 30
أفضل الممارسات
- استخدم حدودًا مختلفة للمستخدمين المصادق عليهم مقابل المجهولين
- طبّق استجابات متدرجة (تحذير قبل الحظر)
- أضف عناوين IP الموثوقة ومفاتيح API إلى القائمة البيضاء
- سجّل انتهاكات تحديد المعدل لأغراض التحليل
تحديد معدل الطلبات أمر أساسي لاستقرار واجهات برمجة التطبيقات والتوزيع العادل للموارد.
التعليقات (0)
اترك تعليقًا
لا توجد تعليقات بعد. كن أول من يشارك أفكاره!