Cara Membatasi Percobaan Login Menggunakan Rate Limiting Laravel
Apa Itu Rate Limiting?
Rate limiting adalah mekanisme untuk membatasi jumlah request yang dapat dilakukan dalam periode tertentu.
Contohnya:
Maksimal 5 percobaan login
dalam 1 menitJika pengguna mencoba login lebih dari batas tersebut, sistem dapat menolak sementara request berikutnya.
Rate limiting tidak hanya dapat digunakan untuk login, tetapi juga untuk:
API.
Form registrasi.
Reset password.
OTP.
Pengiriman email.
Endpoint sensitif lainnya.
Mengapa Login Perlu Dibatasi?
Tanpa pembatasan, penyerang dapat mencoba banyak kombinasi username dan password secara otomatis.
Contohnya:
Request 1 → Password salah
Request 2 → Password salah
Request 3 → Password salah
...
Request 10.000 → Password salahRate limiting membuat percobaan tersebut lebih sulit dilakukan dalam jumlah besar.
1. Membuat Rate Limiter
Laravel menyediakan RateLimiter untuk membuat aturan pembatasan request.
Contohnya pada:
app/Providers/AppServiceProvider.phpTambahkan:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;Kemudian pada method boot():
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by(
strtolower(
$request->input('login')
) . '|' . $request->ip()
);
});Konfigurasi tersebut memberikan batas:
5 percobaan per menitberdasarkan kombinasi identitas login dan IP address.
2. Terapkan Rate Limiter pada Route
Pada route login:
Route::post(
'/login',
[AuthController::class, 'login']
)->middleware('throttle:login');Sekarang setiap request menuju endpoint login akan melewati rate limiter.
Alurnya:
User
↓
POST /login
↓
Rate Limiter
↓
Apakah melebihi batas?
↓
Tidak → Proses Login
Ya → Tolak Request3. Menggunakan IP Address Saja
Jika ingin membatasi berdasarkan IP:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by($request->ip());
});Namun, pendekatan ini perlu hati-hati.
Pada jaringan kantor, sekolah, atau perusahaan, banyak pengguna dapat menggunakan satu IP publik yang sama.
Akibatnya, satu pengguna yang terlalu banyak mencoba login dapat memengaruhi pengguna lainnya.
4. Menggunakan Username atau Email
Alternatifnya:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by(
strtolower(
$request->input('login')
)
);
});Namun, pembatasan hanya berdasarkan username juga memiliki kelemahan karena penyerang dapat mencoba banyak username berbeda.
Karena itu, kombinasi identitas dan IP sering lebih masuk akal untuk login.
5. Kombinasikan User dan IP
Contoh yang lebih seimbang:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by(
strtolower(
$request->input('login')
) . '|' . $request->ip()
);
});Contoh:
admin|192.168.1.10berbeda dengan:
admin|192.168.1.20Dengan demikian, pembatasan tidak hanya bergantung pada username atau IP saja.
6. Memberikan Pesan Ketika Limit Terlampaui
Laravel dapat mengembalikan response ketika batas request sudah tercapai.
Contohnya:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by(
strtolower(
$request->input('login')
) . '|' . $request->ip()
)
->response(function () {
return response()->json([
'message' =>
'Terlalu banyak percobaan login. Silakan coba lagi nanti.'
], 429);
});
});HTTP status:
429 Too Many Requestsdigunakan untuk menunjukkan bahwa request telah melebihi batas.
7. Menentukan Batas yang Berbeda
Tidak semua endpoint harus memiliki batas yang sama.
Contohnya:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5);
});
RateLimiter::for('otp', function (Request $request) {
return Limit::perMinute(3);
});
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60);
});Kemudian:
Route::post(
'/login',
...
)->middleware('throttle:login');
Route::post(
'/send-otp',
...
)->middleware('throttle:otp');
Route::get(
'/api/products',
...
)->middleware('throttle:api');Dengan cara ini setiap fitur dapat memiliki kebijakan sendiri.
8. Rate Limiting Setelah Login Gagal
Rate limiting dapat dikombinasikan dengan pengecekan login.
Contohnya:
public function login(Request $request)
{
$request->validate([
'login' => ['required', 'string'],
'password' => ['required', 'string'],
]);
if (!Auth::attempt([
'email' => $request->login,
'password' => $request->password,
])) {
return back()->withErrors([
'login' =>
'Email atau password salah.',
]);
}
$request->session()->regenerate();
return redirect('/dashboard');
}Namun, rate limiting sebaiknya tetap berada pada middleware atau mekanisme pembatasan request sehingga endpoint terlindungi bahkan sebelum proses autentikasi dijalankan.
9. Menggunakan RateLimiter Secara Manual
Laravel juga menyediakan facade RateLimiter untuk kebutuhan yang lebih khusus.
Contohnya:
use Illuminate\Support\Facades\RateLimiter;Periksa apakah sudah mencapai batas:
if (RateLimiter::tooManyAttempts(
$key,
5
)) {
// Tolak request
}Tambahkan percobaan:
RateLimiter::hit(
$key,
60
);Dapatkan jumlah percobaan:
$attempts = RateLimiter::attempts($key);Pendekatan ini berguna jika aturan rate limiting membutuhkan kontrol lebih detail.
10. Reset Rate Limit
Rate limit juga dapat dihapus secara manual:
RateLimiter::clear($key);Contohnya setelah autentikasi berhasil:
if (Auth::attempt($credentials)) {
RateLimiter::clear($key);
$request->session()->regenerate();
return redirect('/dashboard');
}Hal ini dapat digunakan ketika aplikasi ingin menghapus hit rate limit setelah login berhasil.
11. Rate Limiting untuk API
Rate limiting sangat penting pada API.
Contohnya:
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)
->by(
$request->user()?->id
?? $request->ip()
);
});Route:
Route::middleware('throttle:api')
->group(function () {
Route::get(
'/products',
[ProductController::class, 'index']
);
});Dengan demikian API tidak dapat dipanggil tanpa batas.
12. Rate Limiting untuk OTP
OTP sebaiknya memiliki batas yang lebih ketat.
Contohnya:
RateLimiter::for('otp', function (Request $request) {
return Limit::perMinute(3)
->by(
$request->input('phone')
. '|' .
$request->ip()
);
});Contoh:
3 OTP / menitHal ini dapat membantu mengurangi penyalahgunaan endpoint pengiriman OTP.
13. Rate Limiting pada Aplikasi Multi-Cabang
Untuk sistem multi-cabang, rate limiting tetap dapat diterapkan berdasarkan user.
Contohnya:
User
↓
Branch
↓
Login
↓
Rate LimiterNamun, jangan menjadikan branch_id sebagai satu-satunya pembeda.
Gunakan kombinasi seperti:
->by(
$request->input('login')
. '|' .
$request->ip()
)agar pembatasan tetap spesifik.
14. Perhatikan Reverse Proxy dan Cloudflare
Jika aplikasi berada di belakang:
Cloudflare
↓
Load Balancer
↓
Nginx
↓
Laravelpastikan Laravel dapat mengenali IP client dengan benar.
Jika tidak, $request->ip() dapat berisi IP proxy, bukan IP pengguna sebenarnya.
Konfigurasi trusted proxy perlu disesuaikan dengan arsitektur server.
Ini penting karena rate limiting yang menggunakan IP sangat bergantung pada informasi alamat client yang benar.
15. Rate Limiting Bukan Pengganti Password yang Kuat
Rate limiting hanyalah salah satu lapisan keamanan.
Tetap gunakan:
Password hashing.
HTTPS.
CSRF protection.
Session regeneration.
Multi-factor authentication.
Validasi input.
Permission.
Monitoring.
Logging.
Account security policy.
Untuk sistem dengan data penting, MFA dapat memberikan perlindungan tambahan meskipun password berhasil diketahui pihak lain.
16. Jangan Membuat Limit Terlalu Ketat
Contohnya:
1 percobaan / 1 menitdapat membuat pengguna normal kesulitan login.
Sebaliknya:
10.000 percobaan / menitterlalu longgar untuk endpoint login.
Gunakan batas berdasarkan kebutuhan aplikasi dan lakukan pengujian.
Contoh awal:
Login → 5 percobaan/menit
OTP → 3 percobaan/menit
API → 60 request/menitNilai tersebut bukan angka wajib dan dapat disesuaikan.
17. Monitoring Rate Limit
Pada production, pantau:
Login gagal
↓
Rate limit terkena
↓
IP / akun
↓
Jumlah percobaan
↓
Waktu kejadianJika satu IP atau akun terus-menerus terkena rate limit, kemungkinan terdapat aktivitas yang perlu diperiksa.
Kesalahan yang Perlu Dihindari
Hanya Membatasi Berdasarkan IP
Bisa mengganggu pengguna yang berada dalam jaringan bersama.
Hanya Membatasi Berdasarkan Username
Penyerang dapat mencoba banyak username.
Tidak Menggunakan HTTPS
Password tetap harus dikirim melalui koneksi terenkripsi.
Rate Limit Terlalu Longgar
Brute-force tetap dapat dilakukan.
Tidak Memantau Log
Serangan berulang dapat tidak diketahui.
Menganggap Rate Limit Sudah Cukup
Rate limiting harus menjadi bagian dari sistem keamanan yang lebih lengkap.
Contoh Implementasi Sederhana
Konfigurasi:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by(
strtolower(
$request->input('login')
) . '|' . $request->ip()
);
});Route:
Route::post(
'/login',
[AuthController::class, 'login']
)->middleware('throttle:login');Hasilnya:
User
↓
Login
↓
Maksimal 5 request/menit
↓
Jika melebihi
↓
HTTP 429Rate Limiting Laravel Bersama Ovla Media
Ovla Media dapat membantu menerapkan keamanan pada aplikasi Laravel, termasuk:
Rate limiting login.
Rate limiting API.
OTP protection.
Role dan permission.
Laravel Sanctum.
Two-factor authentication.
Session security.
Audit log.
Monitoring server.
Security hardening.
Implementasi dapat disesuaikan untuk aplikasi Point of Sales, klinik, inventory, CRM, sistem multi-cabang, maupun aplikasi bisnis custom.
Kesimpulan
Rate limiting merupakan mekanisme penting untuk membatasi jumlah request ke endpoint Laravel.
Untuk login, salah satu pendekatan yang dapat digunakan adalah:
Email / Username
+
IP Address
↓
Rate Limiter
↓
5 percobaan / menitImplementasi dasarnya:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by(
strtolower(
$request->input('login')
) . '|' . $request->ip()
);
});Kemudian gunakan:
->middleware('throttle:login')pada route login.
Dengan rate limiting yang dikombinasikan dengan password hashing, HTTPS, MFA, session security, dan monitoring, aplikasi Laravel dapat memiliki perlindungan yang lebih baik terhadap percobaan login berlebihan dan serangan brute-force.
Artikel Terkait
Cara Membuat Sinkronisasi Stok Antar-Aplikasi Menggunakan Laravel API
Sinkronisasi stok antar-aplikasi memungkinkan jumlah persediaan tetap konsisten antara sistem seperti POS, inventory, marketplace, dan gudang. Laravel API dapat digunakan untuk mengirim perubahan stok secara otomatis sehingga setiap aplikasi memiliki informasi persediaan yang lebih akurat.
Cara Membuat Login Menggunakan Email atau Username di Laravel
Laravel dapat dibuat agar pengguna login menggunakan email atau username dalam satu form. Dengan validasi yang tepat, sistem dapat mencari akun berdasarkan salah satu identitas tersebut tanpa membuat halaman login terpisah.
Cara Membuat Audit Log Aktivitas Pengguna di Laravel
Audit log Laravel digunakan untuk mencatat aktivitas pengguna di dalam aplikasi, seperti login, logout, membuat data, mengubah data, dan menghapus data. Dengan audit log, administrator dapat mengetahui siapa yang melakukan perubahan, kapan aktivitas terjadi, dan data apa yang terpengaruh.