['limit' => 20, 'window' => 60], // 每IP每分钟10次 'mobile' => ['limit' => 20, 'window' => 3600] // 每手机号每小时5次 ]; public function handle($request, \Closure $next) { $mobile = $request->param('mobile'); $ip = $request->ip(); // IP频率检查 $ipKey = "rate:ip:{$ip}"; if (!$this->checkRate($ipKey, $this->rules['ip'])) { return $this->tooManyRequests('IP请求过于频繁'); } // 手机号频率检查 $mobileKey = "rate:mobile:{$mobile}"; if (!$this->checkRate($mobileKey, $this->rules['mobile'])) { return $this->tooManyRequests('该手机号请求过于频繁'); } return $next($request); } protected function checkRate(string $key, array $rule): bool { $count = Cache::get($key, 0); if ($count >= $rule['limit']) { return false; } Cache::inc($key); if ($count === 0) { Cache::expire($key, $rule['window']); } return true; } protected function tooManyRequests(string $message): Response { return json([ 'code' => 429, 'msg' => $message, 'data' => null ])->code(429); } }