Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Do you want to set a Limit on Login attempts in the Laravel application?
This step-by-step tutorial helps you learn how to throttle too many attempts in the admin and user Login form in the Laravel application with the help of the Throttle Rate Limiting trait.
Such restriction is translatable at your discretion. Does laravel custom authenticate throttling if you decide to? It is incredibly easy. Limit authenticate attempts from the throttle characteristic can also be transmuted.
Throttling for authenticates is one of Laravel’s less well-known capabilities. By default, users who attempt to log in via the usual Laravel authenticate form more than five times in a minute will receive a different error message.
Let’s see how we may limit authenticate actions in Laravel now. In order to understand laravel throttling and how it functions, we also visually decipher the Laravel authenticate throttling class.
To perform the throttle, we will create a template architecture for the login form, please follow the folder structure below.
Create a folder name components :
Create these 3 files given below :
Create a folder name layouts:
Create a file given below :
template.blade.php
Create a file name login:
resources\views\components\form-card.blade.php
<form {{ $attributes->merge(['class'=>'card shadow']) }}> <div class="card-header p-1 bg-primary"></div> <div class="card-body"> {{ $slot }} </div> </form>
resources\views\components\alert.blade.php
@props(['type']) <div class="alert shadow-sm alert-{{ $type }}" role="alert">{{ $slot }}</div>
resources\views\components\input.blade.php
@props(['label','name','type']) <div class="form-group"> <label>{{ $label }}</label> <input type="{{ $type}}" name="{{ $name }}" class="form-control{{ $errors->has($name) ? ' is-invalid':'' }}"> @error($name) <div class="invalid-feedback">{{ $message }}</div> @enderror </div>
resources\views\layouts\template.blade.php
<!doctype html> <html lang="en"> <head> <title>{{ config('app.name') }}</title> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"> </head> <body> <div class="container mt-5"> @yield('container') </div> <!-- Optional JavaScript --> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script> </body> </html>
resources\views\login.blade.php
@extends('layouts.template') @section('container') <div class="row"> <div class="col-6 offset-3"> <x-form-card method="post" action="{{ route('user.login') }}" autocomplete="off"> @if ($errors->any() && $retries > 0) <x-alert type="warning"> Remaining {{ $retries }} attempt. </x-alert> @endif @if ($retries <= 0) <x-alert type="danger"> Please try again after {{ $seconds }} seconds. </x-alert> @endif @csrf <h4>Limit - Throttle Request, RateLimiter</h4> <x-input label="Email" name="email" type="email" /> <x-input label="Password" name="password" type="password" /> <div class="form-group"> <button type="submit">LOGIN</button> </div> </x-form-card> </div> </div> @endsection
Create a controller
php artisan make:controller LoginController
Configure RateLimiting
app\Providers\RouteServiceProvider.php
<?php namespace App\Providers; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; use Illuminate\Http\Request; use Illuminate\Support\Facades\RateLimiter; use Illuminate\Support\Facades\Route; class RouteServiceProvider extends ServiceProvider { /** * The path to the "home" route for your application. * * This is used by Laravel authentication to redirect users after login. * * @var string */ public const HOME = '/home'; public function boot() { $this->configureRateLimiting(); $this->routes(function () { Route::prefix('api') ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); }); } /** * Configure the rate limiters for the application. * * @return void */ protected function configureRateLimiting() { RateLimiter::for('api', function (Request $request) { return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip()); }); RateLimiter::for('login', function(Request $request){ $key = "login.".$request->ip(); $max = 5; // attempt $decay = 60; // seconds if(RateLimiter::tooManyAttempts($key,$max)){ return back()->with("message","Too Many Requests"); } else { RateLimiter::hit($key,$decay); } }); } }
Define routes
routes\web.php
<?php use Illuminate\Support\Facades\Route; Route::get('/login',[App\Http\Controllers\LoginController::class,'formLogin']); Route::post('/login',[App\Http\Controllers\LoginController::class,'login']) ->name('user.login') ->middleware("throttle:login");
app\Http\Controllers\LoginController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use RateLimiter; class LoginController extends Controller { public function formLogin() { $key = "login.".request()->ip(); return view('login',[ 'key' => $key, 'retries' => RateLimiter::retriesLeft($key, 5), 'seconds' => RateLimiter::availableIn($key), ]); } public function login(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); RateLimiter::clear("login.".$request->ip()); //write here logic for if creds match from records return "Admin Dashboard"; } }
I hope that this article helped you learn How to Set Rate Limit On Routes and implement limit login attempts In Laravel 9, with the help of the Laravel throttle example. You may also want to check out our guide on How To Create Factory In Laravel 9 example in the Laravel application.
Read also:- Define A Variable Construct Method And Use It In All Methods In Laravel.