首页 文章

ThrottleRequestMiddleware用于laravel 5.6中的api路由

提问于
浏览
1

我已经 Build 了api路由作为json资源返回帖子,当我在api路由上放置中间件'apiThrottle:5,1'它只显示结果两次然后在第三个它将生成json响应'Too许多尝试......'

但是,当我将中间件添加到Web路由时,它将继续显示最大化次数的结果(在这种情况下为5),然后生成“尝试次数太多......”

网站路线: https://project.test/

Route::middleware('apiThrottle:5,1')->get('/', function (){
     return 'Web Route';
});

Api路线: https://project.test/api/

Route::middleware('apiThrottle:5,1')->get('/', function (){
     return 'API Route';
});

中间件:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Middleware\ThrottleRequests;

class ThrottleRequestsMiddleware extends ThrottleRequests
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @param  int $maxAttempts
     * @param  int $decayMinutes
     * @return mixed
     */
    public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
    {
        $key = $this->resolveRequestSignature($request);

        $maxAttempts = $this->resolveMaxAttempts($request, $maxAttempts);

        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            return $this->buildJsonResponse($key, $maxAttempts);
        }

        $this->limiter->hit($key, $decayMinutes);

        $response = $next($request);

        return $this->addHeaders(
            $response, $maxAttempts,
            $this->calculateRemainingAttempts($key, $maxAttempts)
        );
    }

    /**
     * Create a 'too many attempts' JSON response.
     *
     * @param  string  $key
     * @param  int  $maxAttempts
     * @return \Symfony\Component\HttpFoundation\Response
     */
    protected function buildJsonResponse($key, $maxAttempts)
    {
        $response = new JsonResponse([
            'error' => [
                'code' => 429,
                'message' => 'Too many attempts, please slow down the request.',
            ],
        ], 429);

        $retryAfter = $this->limiter->availableIn($key);

        return $this->addHeaders(
            $response, $maxAttempts,
            $this->calculateRemainingAttempts($key, $maxAttempts, $retryAfter),
            $retryAfter
        );
    }
}

Kernel.php

/**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        .
        .
        .
        'apiThrottle' => \App\Http\Middleware\ThrottleRequestsMiddleware::class,
    ];

Web路由标头:请求和响应

Content-Security-Policy: default-src 'none' ; script-src resource:; 
X-Firefox-Spdy: h2
cache-control: no-cache, private
content-type: application/json
date: Wed, 18 Apr 2018 11:57:50 GMT
retry-after: 53
server: nginx/1.13.6
set-cookie: XSRF-TOKEN=eyJpdiI6ImpRdGlIXC9KbnV3QTY2MkpKbEZUQ3d3PT0iLCJ2YWx1ZSI6IlU5YXFkZmpVXC9nMHpXSW5zK2RUZFlTVTA0N0YzaE9TeURpSHJlV0FUb1NkXC9rN3dvUUdVbzgwNHQ4MCtDU04rYjBNSHB6U2dsUzZ6cys2cGY5N1dUQVE9PSIsIm1hYyI6IjAzMTRkZTdkNmEwMzk5ODZhMTQ2ODhmYTJjOWE2ODIzODQ1YzQ0OThhY2I2NWUxOTk5MDRmNDc0ZjBjMmNjMDgifQ%3D%3D; expires=Wed, 18-Apr-2018 13:57:50 GMT; Max-Age=7200; path=/
larablog_session=eyJpdiI6IkZqaGZVUk10bFNpb2hUc2xPMXdBbVE9PSIsInZhbHVlIjoiY0hoXC9qMHFWdENIOEZZK3BaUklhMjZtQ2JoS2IwQlRTV053clUyQVd0RmpxTlRmMlVRc1Q4QW8zYUMwZSs0dmFuM3U2N3A2ZGJCZTBaN2JwdHJDSE13PT0iLCJtYWMiOiI1YzQ0ZTNjOGI4NDI3ZDg4NTI5MDQyMDRiMTc3ODk3OGZkYjk4OWJmNzhkODFkM2UwZGU1MTM0NDdmNjIxYTY1In0%3D; expires=Wed, 18-Apr-2018 13:57:50 GMT; Max-Age=7200; path=/; HttpOnly
x-ratelimit-limit: 5
x-ratelimit-remaining: 0
x-ratelimit-reset: 1524052723

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
Cache-Control: max-age=0
Connection: keep-alive
Cookie: XSRF-TOKEN=eyJpdiI6IkNibkJQOUM3clJscElSWGZrcDVoZGc9PSIsInZhbHVlIjoiMzJuZGljNnRzUFoxNVVOYVZscFJBRElqMHJGSGxYa2dqVXkwR0VtZlhpQUFLUkI4cHJnOFdLSGIwdEdmRnA2R2Y5WHRXZHNtTFwvUVVpc2xKM1lQVHV3PT0iLCJtYWMiOiJmNmRjMjQwMDllOWFhZGY2Y2Q2YTVmYzFjZGQxNTE4MTk3ZjRkYWUyMTA2OWY0Y2E3NGNjYTg5MmEzYTZmZjJkIn0%3D; larablog_session=eyJpdiI6IlwvUm55cHBaTVdnR21rbkJVU05DUXVBPT0iLCJ2YWx1ZSI6IkJlYVV3dXB6SUNjMkRrUHJ2bTN2R3RUa294aVpjelJlTVFCUENXVldpSzlKNWdYUTdqeHJtY1JEWXV5UUpvbUc0bHB4UG5hcGltTG9OSVYrdjBMS29BPT0iLCJtYWMiOiI0M2ZjYWMyNjY0MjFkYTlhZjZkZmQ5MjVkMDFhODZiODFiNjQ4OGIzOTViZTNmY2E2NmNhMjQzYmRiY2I4ODdhIn0%3D
Host: project.test
Referer: https://project.test/
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0

API路由标头:请求和响应

Content-Security-Policy: default-src 'none' ; script-src resource:; 
X-Firefox-Spdy: h2
cache-control: no-cache, private
content-type: application/json
date: Wed, 18 Apr 2018 11:55:55 GMT
retry-after: 57
server: nginx/1.13.6
x-ratelimit-limit: 60
x-ratelimit-remaining: 55
x-ratelimit-reset: 1524052612

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
Cache-Control: max-age=0
Connection: keep-alive
Cookie: XSRF-TOKEN=eyJpdiI6InFHZVFHNDg3M2hpcG9rUHd2WnlQclE9PSIsInZhbHVlIjoiQW1oZFZXbFc3NFhwVnpBTGZsM0tKbGlBaDhUNkM0TXpqMzZTb1FHUUI4bFk5XC9wWEdyK0lOZThyZ25vT2FLUHN2MXFZZGtuaVFta1lLdzBxZU9FdnR3PT0iLCJtYWMiOiJhMjM3MzA5ZDI1MmNjMjE0YTkyZjA4ODAyMzNmNDQwM2JjNTJjYzY4NzcyYWIwYWE5NjdmMWI0OTgwNjg5OGY4In0%3D; larablog_session=eyJpdiI6IjhTMnZTSmhMd3lSOUlLZzREd1BEN0E9PSIsInZhbHVlIjoiMVh2SFh4azM2RTJxRWFkV0g4YUxMUmRhVyt0bUVOYkZzbnZLRnBVb1gxQXB5OUQ2Y2lFZmNpMGt0NmNXSVlKSDFoWlE1aVZra2ROZEtYSzNpRzlVbGc9PSIsIm1hYyI6IjhmMDNmNzgzYWViODU3NzQ0MTExMzBlNWI1OTc0MTY5YzI2ZDZkZDQ2OThmZTM3NDJjZjA4MTkxN2Y0YTVhNmQifQ%3D%3D
Host: project.test
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0

请指教,

1 回答

  • 1

    api节流器声明两次,因此命中两次 .

    对于所有api路由,在 app/Http/Kernel.php 上声明了节流中间件

    'api' => [
            'throttle:60,1',
            'bindings',
        ],
    

    要解决此问题,您必须删除内核文件中的api限制,并且可以在api路由文件_680925中定义单独的限制中间件组,如下所示:

    // limit to 60 hits in 1 min
    Route::group(['middleware' => ['throttle:60,1'], 'prefix' => 'foo'], function () {
        Route::get('/', 'FooController@fooMethod');
    });
    
    // limit to 500 hits in 1 min
    Route::group(['middleware' => ['throttle:500,1'], 'prefix' => 'bar'], function () {
        Route::get('/', 'BarController@barMethod');
    });
    

相关问题