Lumen 使用 throttle 限制接口訪問頻率

前言

今天碰到過這樣一個狀況,我須要限制用戶請求某個API接口的頻率,好比登陸、反饋等提交操做,通過一番搜索+折騰,總算是實現了。javascript

Laravel 5.2的新特性中增長了一個throttle中間件,經過它能夠在路由層限制API訪問的頻率。例如限制頻率爲1分鐘50次,若是一分鐘內超過了這個限制,它就會響應:429: Too Many Attempts。php

但我在項目中使用的是Lumen框架(它只有Laravel中的一部分功能),它並無集成這個中間件,因此本文主要是講述如何在Lumen框架中加入throttle中間件。java

開始

首先咱們要在app\Http\Middleware中新建ThrottleRequests.php文件。git

而且把如下連接中的代碼拷貝到這個文件中:github

github.com/illuminate/…bootstrap

接着修改文件中的命名空間:app

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,寫入如下代碼:post

<?php

namespace App\Exceptions;

use Exception;

class ThrottleException extends Exception{
    protected $isReport = false;

    public function isReport(){
        return $this->isReport;
    }
}
複製代碼

app/Exceptions/Handler.php捕獲該拋出異常,在render方法增長如下判斷:ui

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次。

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

相關文章
相關標籤/搜索