前言
今天碰到過這樣一個情況,我需要限制使用者請求某個API
介面的頻率,比如登入、反饋等提交操作,經過一番搜尋+折騰,總算是實現了。
在
Laravel 5.2
的新特性中增加了一個throttle
中介軟體,通過它可以在路由層限制API
訪問的頻率。例如限制頻率為1分鐘50次,如果一分鐘內超過了這個限制,它就會響應:429: Too Many Attempts。
但我在專案中使用的是Lumen
框架(它只有Laravel
中的一部分功能),它並沒有整合這個中介軟體,所以本文主要是講述如何在Lumen
框架中加入throttle
中介軟體。
開始
首先我們要在app\Http\Middleware
中新建ThrottleRequests.php
檔案。
並且把以下連結中的程式碼拷貝到這個檔案中:
接著修改檔案中的名稱空間:
namespace App\Http\Middleware;
複製程式碼
標記同一使用者端請求
因為Lumen
框架缺失部分功能,我們需要修改ThrottleRequests.php
中的resolveRequestSignature
方法:
protected function resolveRequestSignature($request){
return sha1( $request->
method() . '|' . $request->
server('SERVER_NAME') . '|' . $request->
path() . '|' . $request->
ip() );
}複製程式碼
丟擲響應
throttle
超過限制時丟擲的是Illuminate\Http\Exceptions\ThrottleRequestsException
,同樣Lumen
框架缺少這個檔案,需要自己定義一下,在app/Exceptions
中新建ThrottleException.php
,寫入以下程式碼:
<
?phpnamespace App\Exceptions;
use Exception;
class ThrottleException extends Exception{
protected $isReport = false;
public function isReport(){
return $this->
isReport;
}
}複製程式碼
在app/Exceptions/Handler.php
捕獲該丟擲異常,在render
方法增加以下判斷:
if ($exception instanceof ThrottleException) {
return response([ 'code' =>
$exception->
getCode(), 'msg' =>
$exception->
getMessage() ], 429);
}複製程式碼
修改ThrottleRequests.php
檔案中的buildException
方法:
protected function buildException($key, $maxAttempts){
$retryAfter = $this->
getTimeUntilNextRetry($key);
$headers = $this->
getHeaders( $maxAttempts, $this->
calculateRemainingAttempts($key, $maxAttempts, $retryAfter), $retryAfter );
// 修改了這一行 return new ThrottleException('Too Many Attempts.', 429);
}複製程式碼
需在檔案頭部中新增這一行:
use App\Exceptions\ThrottleException;
註冊中介軟體
在bootstrap/app.php
中註冊:
$app->
routeMiddleware([ 'throttle' =>
App\Http\Middleware\ThrottleRequests::class,]);
複製程式碼
到這裡我們就加入成功了,接著在路由中新增中介軟體即可:
$router->
group(['middleware' =>
['throttle:10,2']],function() use ($router){
$router->
post('feedback','UserController@addFeedback');
});
複製程式碼
其中throttle:10,2
表示的是2分鐘內訪問10次。
注:此文為原創文章,如需轉載,請註明出處。