first commit
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Auth;
|
||||
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Illuminate\Cache\RateLimiter;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Login throttling, keyed on the submitted username and the client IP.
|
||||
*
|
||||
* This was laravel/ui's ThrottlesLogins trait plus Vanguard's overrides of it,
|
||||
* inlined here so the package is no longer a dependency. The limits come from
|
||||
* application settings rather than from properties, which is why maxAttempts()
|
||||
* and decayMinutes() are methods.
|
||||
*/
|
||||
trait ThrottlesLogins
|
||||
{
|
||||
/**
|
||||
* Get the login username to be used by the controller.
|
||||
*/
|
||||
public function username(): string
|
||||
{
|
||||
return 'username';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user has too many failed login attempts.
|
||||
*/
|
||||
protected function hasTooManyLoginAttempts(Request $request): bool
|
||||
{
|
||||
return $this->limiter()->tooManyAttempts(
|
||||
$this->throttleKey($request),
|
||||
$this->maxAttempts()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the login attempts for the user.
|
||||
*/
|
||||
protected function incrementLoginAttempts(Request $request): void
|
||||
{
|
||||
$this->limiter()->hit(
|
||||
$this->throttleKey($request),
|
||||
$this->decayMinutes() * 60
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the login locks for the given user credentials.
|
||||
*/
|
||||
protected function clearLoginAttempts(Request $request): void
|
||||
{
|
||||
$this->limiter()->clear($this->throttleKey($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event when a lockout occurs.
|
||||
*/
|
||||
protected function fireLockoutEvent(Request $request): void
|
||||
{
|
||||
event(new Lockout($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine how many retries are left for the user.
|
||||
*/
|
||||
protected function retriesLeft(Request $request): int
|
||||
{
|
||||
$attempts = $this->limiter()->attempts(
|
||||
$this->throttleKey($request)
|
||||
);
|
||||
|
||||
return $this->maxAttempts() - $attempts + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the user after determining they are locked out.
|
||||
*
|
||||
* Redirects rather than throwing a 429 ValidationException, so the lockout
|
||||
* message lands on the login form like any other error.
|
||||
*/
|
||||
protected function sendLockoutResponse(Request $request): RedirectResponse
|
||||
{
|
||||
$seconds = $this->limiter()->availableIn(
|
||||
$this->throttleKey($request)
|
||||
);
|
||||
|
||||
return redirect('login')
|
||||
->withInput($request->only($this->username(), 'remember'))
|
||||
->withErrors([
|
||||
$this->username() => $this->getLockoutErrorMessage($seconds),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the login lockout error message.
|
||||
*/
|
||||
protected function getLockoutErrorMessage(int $seconds): string
|
||||
{
|
||||
return trans('auth.throttle', ['seconds' => $seconds]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the throttle key for the given request.
|
||||
*/
|
||||
protected function throttleKey(Request $request): string
|
||||
{
|
||||
return Str::transliterate(
|
||||
Str::lower($request->input($this->username())).'|'.$request->ip()
|
||||
);
|
||||
}
|
||||
|
||||
protected function limiter(): RateLimiter
|
||||
{
|
||||
return app(RateLimiter::class);
|
||||
}
|
||||
|
||||
protected function maxAttempts(): int
|
||||
{
|
||||
return (int) setting('throttle_attempts', 5);
|
||||
}
|
||||
|
||||
protected function decayMinutes(): int
|
||||
{
|
||||
$lockout = (int) setting('throttle_lockout_time');
|
||||
|
||||
return max($lockout, 1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user