Lumen 使用 throttle 限制介面訪問頻率

4Ark發表於2019-01-18

前言

今天碰到過這樣一個情況,我需要限制使用者請求某個API介面的頻率,比如登入、反饋等提交操作,經過一番搜尋+折騰,總算是實現了。

Laravel 5.2的新特性中增加了一個throttle中介軟體,通過它可以在路由層限制API訪問的頻率。例如限制頻率為1分鐘50次,如果一分鐘內超過了這個限制,它就會響應:429: Too Many Attempts。

但我在專案中使用的是Lumen框架(它只有Laravel中的一部分功能),它並沒有整合這個中介軟體,所以本文主要是講述如何在Lumen框架中加入throttle中介軟體。

開始

首先我們要在app\Http\Middleware中新建ThrottleRequests.php檔案。

並且把以下連結中的程式碼拷貝到這個檔案中:

github.com/illuminate/…

接著修改檔案中的名稱空間:

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,寫入以下程式碼:

<
?php
namespace 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次。

注:此文為原創文章,如需轉載,請註明出處。

來源:https://juejin.im/post/5c41bea8f265da61171cfecf

相關文章