修正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, 39;|')) { $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,当访问次数超过限定时抛出非常
<?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()], 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来配置