Laravel 自带了一个 Throttle
中间件,默认的设置是 1 分钟内请求超过 60 次就会触发这个,然后服务器就会返回 429 Too Many Requests
这个默认配置可以在 app\Http\Kernel.php
中看到
更多参考文档:https://www.cnblogs.com/toughlife/p/10601069.html
Laravel 默认 返回的是一个 429
的 html
页面,做 api
的话这样不太好
我们新建一个中间件,来替换掉原来的中间件
artisan
命令新建一个中间件:php artisan make:middleware ThrottleRequests
编写代码:
继承原来的ThrottleRequests
,稍微修改一下就可以了。
如果限制时间要修改成秒的话, 请查看 :$this->limiter->hit($key,&decayMinutes * 60)
$decayMinutes * 60
,如果 decayMinutes
= 1
的话, 那么就是限制一分钟, 1*60
那么修改成 $this->limiter->hit($key,&decayMinutes)
,就成限制秒了
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Response;
class ThrottleRequests extends \Illuminate\Routing\Middleware\ThrottleRequests
{
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->buildException($key, $maxAttempts);
//throw $this->buildException($key, $maxAttempts);
// 原来的是抛出异常,修改成直接返回
}
//去掉 `* 60` 限制秒级,加上去限制分钟,要限制其他单位,可以自己算的
$this->limiter->hit($key, $decayMinutes);
//$this->limiter->hit($key, $decayMinutes * 60);
$response = $next($request);
return $this->addHeaders(
$response, $maxAttempts,
$this->calculateRemainingAttempts($key, $maxAttempts)
);
}
protected function buildException($key, $maxAttempts)
{
$retryAfter = $this->limiter->availableIn($key);
//要返回的数据
$message = json_encode([
'code' => 429,
'data' => null,
'msg' => '您的请求太频繁,已被限制请求',
'retryAfter' => $retryAfter,
], 320);
$response = new Response($message, 200);
return $this->addHeaders(
$response, $maxAttempts,
$this->calculateRemainingAttempts($key, $maxAttempts, $retryAfter),
$retryAfter
);
}
protected function addHeaders(\Symfony\Component\HttpFoundation\Response $response, $maxAttempts, $remainingAttempts, $retryAfter = null)
{
// 添加 `response` 头 为 `json`
$response->headers->add(
['Content-Type' => 'application/json;charset=utf-8']
);
return parent::addHeaders($response, $maxAttempts, $remainingAttempts, $retryAfter);
}
}
有话要说