在laravel 5.6及以上版本中框架中已自带ThrottleRequests,但是为了更好的处理消息,我们可以再新加一个中间件,来更方便的处理相应信息
第一步: php artisan make:middleware ThrottleRequests
在ThrottleRequest类中放入以下代码
namespace AppHttpMiddleware; use Closure; use IlluminateCacheRateLimiter; use SymfonyComponentHttpFoundationResponse; class ThrottleRequests { /** * The rate limiter instance. * * @var IlluminateCacheRateLimiter */ protected $limiter; /** * Create a new request throttler. * * @param IlluminateCacheRateLimiter $limiter */ public function __construct(RateLimiter $limiter) { $this->limiter = $limiter; } /** * Handle an incoming request. * * @param IlluminateHttpRequest $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); if ($this->limiter->tooManyAttempts($key, $maxAttempts, $decayMinutes)) { return $this->buildResponse($key, $maxAttempts); } $this->limiter->hit($key, $decayMinutes); $response = $next($request); return $this->addHeaders( $response, $maxAttempts, $this->calculateRemainingAttempts($key, $maxAttempts) ); } /** * Resolve request signature. * * @param IlluminateHttpRequest $request * @return string */ protected function resolveRequestSignature($request) { return $request->fingerprint(); } /** * Create a 'too many attempts' response. * * @param string $key * @param int $maxAttempts * @return IlluminateHttpResponse */ protected function buildResponse($key, $maxAttempts) { $message = json_encode([ 'data' => [ 'messsage' => '请求次数太多' //may comes from lang file ,'code' => 429, //your custom code 'data'=>'' ] ]); $response = new Response($message, 429); $retryAfter = $this->limiter->availableIn($key); return $this->addHeaders( $response, $maxAttempts, $this->calculateRemainingAttempts($key, $maxAttempts, $retryAfter), $retryAfter ); } /** * Add the limit header information to the given response. * * @param SymfonyComponentHttpFoundationResponse $response * @param int $maxAttempts * @param int $remainingAttempts * @param int|null $retryAfter * @return IlluminateHttpResponse */ protected function addHeaders(Response $response, $maxAttempts, $remainingAttempts, $retryAfter = null) { $headers = [ 'X-RateLimit-Limit' => $maxAttempts, 'X-RateLimit-Remaining' => $remainingAttempts, ]; if (!is_null($retryAfter)) { $headers['Retry-After'] = $retryAfter; $headers['Content-Type'] = 'application/json'; } $response->headers->add($headers); return $response; } /** * Calculate the number of remaining attempts. * * @param string $key * @param int $maxAttempts * @param int|null $retryAfter * @return int */ protected function calculateRemainingAttempts($key, $maxAttempts, $retryAfter = null) { if (!is_null($retryAfter)) { return 0; } return $this->limiter->retriesLeft($key, $maxAttempts); } }
使用,可以在api.php 路由中这样使用
$api = app('DingoApiRoutingRouter'); $api->version('v1', function ($api) { $api->group(['middleware'=>'throttle:3,1'] , function ($api) { 其中3表示请求次数,1为分钟。以上设置为每分钟只能请求3 次
或者在Kernel.php $middlewareGroups中配置
。。。。。 'api' => [ 'throttle:3,1', 'bindings', ],