Modern API tasarımlarında Rate Limiting (Hız Sınırlandırma), hem API güvenliğini sağlamak hem de kaynakları korumak için kritik bir öneme sahiptir. Laravel, varsayılan olarak ThrottleMiddleware ve Rate Limiting özellikleriyle bu alanda güçlü bir çözüm sunar. Bu yazıda Laravel'deki rate limiting stratejilerini, temel ve ileri seviye kullanım yöntemlerini detaylı bir şekilde ele alacağız.
Rate Limiting Nedir?
Rate Limiting, bir API'ye belirli bir süre içinde gelen isteklerin sayısını sınırlama işlemidir. Örneğin:
- Bir kullanıcı bir dakika içinde en fazla 60 istek yapabilir.
- Sınırı aşan kullanıcıya 429 (Too Many Requests) HTTP hatası döner.
Bu mekanizma şunları sağlar:
- API'nin Performansını Koruma: Aşırı yüklenme durumlarını önler.
- DDoS Saldırılarını Azaltma: Kötü niyetli yoğun trafik saldırılarına karşı koruma sağlar.
- Adil Kullanım: API kaynaklarının eşit şekilde kullanılmasını sağlar.
Laravel'de Rate Limiting Nasıl Kullanılır?
Laravel'de rate limiting, ThrottleMiddleware ve RateLimiter sınıfı üzerinden yönetilir.
1. Temel Rate Limiting
Route tanımlamalarında throttle middleware'i kullanarak belirli bir sınır belirleyebilirsiniz:
Route::middleware('throttle:60,1')->group(function () {
Route::get('/api/users', [UserController::class, 'index']);
});
Bu örnekte:
- 60: Bir dakikada en fazla 60 istek yapılabilir.
- 1: Süre (dakika olarak).
Sınırı aşan isteklerde Laravel, otomatik olarak bir 429 Too Many Requests hatası döner.
2. Global Rate Limiting (RateLimiter Sınıfı)
Laravel 8 ile birlikte gelen yeni RateLimiter sınıfı, daha dinamik ve esnek hız sınırlamaları yapmanızı sağlar.
Örnek: Kullanıcıya Özel Limitler
Kullanıcının kimlik doğrulamasına göre farklı limitler tanımlayabilirsiniz:
use Illuminate\Support\Facades\RateLimiter;
RateLimiter::for('global', function ($request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});
Bu örnek şunları yapar:
- Kimlik doğrulaması yapılmış kullanıcılar için bir dakikada 100 istek.
- Anonim kullanıcılar için bir dakikada 10 istek.
Tanımlanan global limiti şu şekilde kullanabilirsiniz:
Route::middleware('throttle:global')->group(function () {
Route::get('/api/products', [ProductController::class, 'index']);
});
3. İleri Seviye Kullanımlar
a. API Anahtarlarına Göre Rate Limiting
Kullanıcıların API anahtarına göre farklı limitler uygulamak için:
RateLimiter::for('api', function ($request) {
$apiKey = $request->header('X-API-KEY');
return $apiKey === 'premium-key'
? Limit::perMinute(1000)->by($apiKey)
: Limit::perMinute(100)->by($apiKey);
});
Bu yöntem, premium kullanıcılar için daha yüksek limitler tanımlamanıza olanak tanır.
b. IP Adresine Göre Rate Limiting
Her IP adresine farklı hız sınırı uygulamak için:
RateLimiter::for('ip', function ($request) {
return Limit::perMinute(50)->by($request->ip());
});
Bu ayar, belirli bir IP adresinden gelen isteklerin sayısını sınırlayacaktır.
c. Zaman Çerçevesine Göre Rate Limiting
Farklı zaman dilimlerinde farklı sınırlar uygulamak için:
RateLimiter::for('dynamic', function ($request) {
$hour = now()->hour;
if ($hour >= 9 && $hour <= 17) { // İş saatleri
return Limit::perMinute(100)->by($request->ip());
}
return Limit::perMinute(10)->by($request->ip());
});
Bu örnekte, iş saatlerinde daha fazla istek yapılmasına izin verilirken diğer saatlerde sınırlama daha düşük tutulmuştur.
Route'larda Rate Limiting Kullanımı
Örneğin:
usersprefix alanı için standart kullanıcılar farklı bir limit uygulayabilir.adminprefix alanı için yönetici işlemleri daha yüksek bir limite sahip olabilir.
1. Prefix Alanlarına Göre Rate Limiting
routes/web.php veya routes/api.php dosyalarınızda bu şekilde yapılandırabilirsiniz:
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\RateLimiter;
// Rate Limiting Tanımları
RateLimiter::for('users', function ($request) {
return Limit::perMinute(50)->by($request->ip());
});
RateLimiter::for('admin', function ($request) {
return Limit::perMinute(100)->by($request->ip());
});
// Kullanıcı Routes
Route::prefix('users')->middleware('throttle:users')->group(function () {
Route::get('/profile', [UserController::class, 'profile']);
Route::post('/update', [UserController::class, 'update']);
});
// Admin Routes
Route::prefix('admin')->middleware('throttle:admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'dashboard']);
Route::post('/settings', [AdminController::class, 'updateSettings']);
});
Açıklamalar:
-
RateLimiter::for() Tanımı:
usersiçin bir dakikada maksimum 50 istek yapılabilir.adminiçin bir dakikada maksimum 100 istek yapılabilir.
-
Prefix Kullanımı:
Route::prefix('users'):/usersalanındaki tüm rotalar içinusersthrottle limiti uygulanır.Route::prefix('admin'):/adminalanındaki tüm rotalar içinadminthrottle limiti uygulanır.
-
Middleware Tanımı:
Her prefix altındathrottle:usersveyathrottle:adminmiddleware'ini ekleyerek sınırlandırmayı devreye alıyoruz.
Kullanıcı ve Yönetici Ayrımı
Eğer kimlik doğrulama (authentication) kullanıyorsanız, farklı kullanıcı türleri için sınırlandırma yapabilirsiniz. Örneğin:
RateLimiter::for('users', function ($request) {
if ($request->user() && $request->user()->isAdmin()) {
return Limit::perMinute(100)->by($request->user()->id);
}
return Limit::perMinute(50)->by($request->user()->id);
});
Bu örnek:
- Yönetici kullanıcılar için (isAdmin kontrolü), bir dakikada 100 istek izni verir.
- Standart kullanıcılar için bir dakikada 50 istek sınırı uygulanır.
Özel Durumlar: Route Bazlı Rate Limiting
Eğer bir prefix altında farklı rotalara farklı limitler uygulamak istiyorsanız:
Route::prefix('users')->group(function () {
Route::get('/profile', [UserController::class, 'profile'])->middleware('throttle:20,1'); // 20 istek/dakika
Route::post('/update', [UserController::class, 'update'])->middleware('throttle:5,1'); // 5 istek/dakika
});
Bu durumda:
/users/profileiçin bir dakikada en fazla 20 istek yapılabilir./users/updateiçin bir dakikada en fazla 5 istek yapılabilir.
Test Edilmesi
Bu yapıyı test etmek için Laravel'in Tinker aracını kullanabilirsiniz. Örneğin:
php artisan tinkerkomutunu çalıştırın.- API'ye birden fazla istek gönderin:
$response = Http::get('http://localhost/users/profile');
$response->status(); // 200 veya 429 döner.
Bu yapılandırmalarla Laravel projelerinizde prefix bazlı, route bazlı veya kullanıcı türüne özel rate limiting stratejileri kolayca oluşturabilirsiniz. Böylece hem API'nizin güvenliğini artırabilir hem de performansını koruyabilirsiniz.
Rate Limiting Hatalarını Yönetmek
Laravel, rate limiting ihlali durumunda otomatik olarak 429 Too Many Requests hatası döner. Ancak, bu mesajı özelleştirebilirsiniz:
use Symfony\Component\HttpFoundation\Response;
RateLimiter::for('custom', function ($request) {
return Limit::perMinute(60)->response(function () {
return response('Limit aşıldı. Lütfen daha sonra tekrar deneyin.', 429);
});
});
Performans ve Güvenlik İçin İpuçları
- Cache Kullanımı: Rate limiting, Laravel'in cache sistemine dayanır. Performansı artırmak için
redisveyamemcachedkullanabilirsiniz. - Test Etme: API rate limiting stratejilerinizi otomatik testlerle doğrulayın.
- Saldırı Tespiti: Anormal yüksek istek trafiğini tespit edip gerekli önlemleri almak için rate limiting ile birlikte loglama araçlarını kullanın.
- Kuyruklara Geçiş: Yoğun işlemleri (ör. e-posta gönderimi) rate limiting ile kuyruklara aktararak API'nin performansını koruyabilirsiniz.
Sonuç
Laravel'in ThrottleMiddleware ve RateLimiter sınıfları, API'lerinizi hız sınırlandırma ile güvenli ve performanslı bir hale getirmek için güçlü araçlar sunar. Kullanıcı gruplarına göre özelleştirilmiş limitler veya IP tabanlı stratejiler gibi ileri seviye yöntemlerle API'nin daha güvenilir ve adil bir şekilde kullanılmasını sağlayabilirsiniz.
Bu yazıda, Laravel'de rate limiting için temel ve gelişmiş yöntemleri detaylı bir şekilde ele aldık. Projelerinizi geliştirme sırasında bu stratejileri kullanarak API'nizin güvenliğini ve performansını artırabilirsiniz.
