| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- <?php
-
- namespace app\common\middleware;
-
- use think\facade\Cache;
- use think\Response;
-
- class RateLimitMiddleware
- {
- // 频率限制配置(单位:秒)
- protected $rules = [
- 'ip' => ['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);
- }
- }
|