From 8b7a7a7b881c973c45426fd5fce6f2b261beacbd Mon Sep 17 00:00:00 2001 From: Lucas Michot Date: Thu, 29 Jun 2017 18:44:57 +0200 Subject: [PATCH] Improve ThrottleRequests. --- .../Routing/Middleware/ThrottleRequests.php | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Routing/Middleware/ThrottleRequests.php b/src/Illuminate/Routing/Middleware/ThrottleRequests.php index c435930c97c6..483ed671fe7f 100644 --- a/src/Illuminate/Routing/Middleware/ThrottleRequests.php +++ b/src/Illuminate/Routing/Middleware/ThrottleRequests.php @@ -3,6 +3,8 @@ namespace Illuminate\Routing\Middleware; use Closure; +use RuntimeException; +use Illuminate\Support\Str; use Illuminate\Support\Carbon; use Illuminate\Cache\RateLimiter; use Symfony\Component\HttpFoundation\Response; @@ -32,7 +34,7 @@ public function __construct(RateLimiter $limiter) * * @param \Illuminate\Http\Request $request * @param \Closure $next - * @param int $maxAttempts + * @param int|string $maxAttempts * @param float|int $decayMinutes * @return mixed */ @@ -40,6 +42,8 @@ public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes { $key = $this->resolveRequestSignature($request); + $maxAttempts = $this->resolveMaxAttempts($request, $maxAttempts); + if ($this->limiter->tooManyAttempts($key, $maxAttempts, $decayMinutes)) { return $this->buildResponse($key, $maxAttempts); } @@ -54,15 +58,41 @@ public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes ); } + /** + * Resolve the number of attempts if the user is authenticated or not. + * + * @param \Illuminate\Http\Request $request + * @param int|string $maxAttempts + * @return int + */ + protected function resolveMaxAttempts($request, $maxAttempts) + { + if (Str::contains($maxAttempts, '|')) { + $parts = explode('|', $maxAttempts, 2); + $maxAttempts = $parts[$request->user() ? 1 : 0]; + } + + return (int) $maxAttempts; + } + /** * Resolve request signature. * * @param \Illuminate\Http\Request $request * @return string + * @throws \RuntimeException */ protected function resolveRequestSignature($request) { - return $request->fingerprint(); + if ($user = $request->user()) { + return sha1($user->getAuthIdentifier()); + } + + if ($route = $request->route()) { + return sha1($route->getDomain().'|'.$request->ip()); + } + + throw new RuntimeException('Unable to generate the request signature. Route unavailable.'); } /**