使用背景
在达能小程序h5版,小程序的部分接口可以在不用登陆的情况下随意调用。为了防止恶意调用接口服务器带来过大的压力,需要对接口调用次数限制,我使用的限制规则是每个ip每个接口一分钟之内最多访问30次,目前项目是使用的lumen框架开发的接口,这里主要说一下如何在Lumen框架中使用throttle中间件来限制客户端接口请求次数
具体方法
1.新建中间件
在app\Http\Middleware中新建ThrottleRequests.php文件,文件下载地址:https://github.com/illuminate/routing/blob/master/Middleware/ThrottleRequests.php
修改ThrottleRequests.php中的resolveRequestSignature方法用来定义我们自己的限制规则
/**
* Resolve the number of attempts if the user is authenticated or not.
*
* @param \Illuminate\Http\Request $request
* @param int|string $maxAttempts
* @return int
*/
protected function resolveMaxAttempts($request, $maxAttempts)
{
if (Str::contains($maxAttempts, '|')) {
$maxAttempts = explode('|', $maxAttempts, 2)[$request->user() ? 1 : 0];
}
if (! is_numeric($maxAttempts) && $request->user()) {
$maxAttempts = $request->user()->{$maxAttempts};
}
return (int) $maxAttempts;
}
2.重新定义异常处理
由于laravel的Throttle在超过频率限制时抛出的异常是一个html页面,但本项目需要以jsonresponse的形式抛给前端,所以需要重新定义异常
在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()], 432);
}
修改ThrottleRequests.php文件中的buildException方法
/**
* Create a 'too many attempts' exception.
*
* @param string $key
* @param int $maxAttempts
* @return \Illuminate\Http\Exceptions\ThrottleRequestsException
*/
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.', 432);
}
注册中间件
$app->routeMiddleware([
'admin.auth' => App\Http\Middleware\AdminAuth::class,
'front.auth' => App\Http\Middleware\FrontAuth::class,
'auth' => App\Http\Middleware\Authenticate::class,
'front.checkEnv' => App\Http\Middleware\CheckEnv::class,
'h5.auth' => App\Http\Middleware\H5Auth::class,
'throttle' => App\Http\Middleware\ThrottleRequests::class
]);
4.使用
$router->group(['middleware' => ['throttle:30']], function () use ($router) {
// 登录
$router->post('auth/login', ['uses' => 'UcAuthController@login']);
$router->get('auth/login', ['uses' => 'UcAuthController@login']);
});
总结
限制IP防刷的机制有很多,我们是在业务层通过throttle中间件和通过nginx两方面来限制的。nginx的限制IP访问次数的配置也很简单,具体可参照https://blog.csdn.net/weixin_33755649/article/details/91599721?utm_source=distribute.pc_relevant.none-task来配置
本文暂时没有评论,来添加一个吧(●'◡'●)