-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use concerns of laravel/ui #25
Comments
Choosing a custom However, I will admit that we forgot to implement the login throttling behaviour that comes from the |
Did this ever materialize? Searching for any sort of login-throttling behaviour in vain. It's not like we can just use throttling middleware from the routes file as livewire POSTs to it's own endpoints and not the component/page route. And the "ThrottleLogins" trait requires use of $request, which we don't have access to in livewire components. Any suggestions? |
You can update your livewire config:
return [
// ...
'middleware_group' => ['web', 'throttle:5,1'],
// ...
]; This will then be applied to all Livewire Components Edit: Otherwise you can take a look at traits where you implement your throttle logic: |
@Jubeki thanks for the pointers! Will the throttling apply to the livewire endpoint (/livewire/*) or just the frontend route (on which you could already use regular laravel route throttling)? Ideally you would only want very conservative/slow throttling applied to the login/register methods. |
The throttling should be applied to the You could make a feature request on https://github.com/livewire/livewire for middleware for components. I will tag Caleb here. Maybe he has some ideas. |
@Jubeki great solution as a fail-safe on all routes but blows up a route with an ugly 403 error. Instead, I found a way to use a validation rule for more specific throttling and a graceful way to relay that to the end user. @glaesser thanks to @stevebauman I was able to come up with a custom throttle validation rule that follows the laravel ui methodology and by extension a custom Lockout Event since both required access to the Request object. Give this a shot when you get the chance: App\Events\Lockout.php<?php
namespace App\Events;
class Lockout
{
public $key, $identifier;
public function __construct(string $key, string $identifier = '')
{
$this->key = $key;
$this->identifier = $identifier;
}
} App\Rules\Throttle.php<?php
namespace App\Rules;
use Illuminate\Cache\RateLimiter;
use Illuminate\Contracts\Validation\Rule;
class Throttle implements Rule
{
protected $throttleKey, $maxAttempts, $decayInMinutes, $event;
public function __construct($throttleKey, $maxAttempts, $decayInMinutes, $event = null)
{
$this->throttleKey = $throttleKey;
$this->maxAttempts = $maxAttempts;
$this->decayInMinutes = $decayInMinutes;
$this->event = $event;
}
public function passes($attribute, $value): bool
{
if ($this->hasTooManyAttempts()) {
if($this->event) {
event(new $this->event($this->throttleKey, $value));
}
return false;
}
$this->incrementAttempts();
return true;
}
public function message()
{
$seconds = $this->limiter()
->availableIn($this->throttleKey);
return trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]);
}
protected function hasTooManyAttempts()
{
return $this->limiter()->tooManyAttempts(
$this->throttleKey, $this->maxAttempts
);
}
protected function limiter()
{
return app(RateLimiter::class);
}
protected function incrementAttempts()
{
$this->limiter()->hit(
$this->throttleKey, $this->decayInMinutes * 60
);
}
} App\Http\Livewire\Auth\Login.php<?php
namespace App\Http\Livewire\Auth;
use App\Events\Lockout;
use App\Rules\Throttle;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Livewire\Component;
class Login extends Component
{
public $ip, $email, $password, $remember = false;
protected function rules(): array
{
return [
'email' => [
'required',
'email',
new Throttle($this->throttleKey(), 5, 1, Lockout::class)],
'password' => ['required'],
];
}
public function mount(Request $request)
{
$this->ip = $request->ip();
}
public function login()
{
$input = $this->validate();
if (Auth::attempt($input, $this->remember)) {
session()->regenerate();
return redirect()->intended(route('home'));
}
return $this->addError('password', trans('auth.failed'));
}
protected function throttleKey()
{
return Str::lower("$this->email|$this->ip");
}
public function render()
{
return view('livewire.auth.login');
}
} |
Many solutions of laravel are not accessible if you are using this preset (including security features).
For example the concern AuthenticatesUsers.
It ships with throttling login attempts and choosing a custom
username()
instead of onlyemail
.Maybe the concerns should be added but then this preset or better
laravel/ui
cannot be uninstalled because the concerns are implemented there.The text was updated successfully, but these errors were encountered: