BannedIpRepository.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. /**
  3. * 禁用IP.
  4. *
  5. * @author jim <jim458734573@gmail.com>
  6. * @date 2020-01-31 10:39:38
  7. */
  8. declare(strict_types=1);
  9. namespace App\Repositories;
  10. use App\Constants\CreatorConstant;
  11. use App\Model\BannedIpModel;
  12. use App\Model\UserModel;
  13. use Carbon\Carbon;
  14. use Hyperf\Redis\Redis;
  15. use KZ2\Repositories\Model\Repository;
  16. use Psr\SimpleCache\CacheInterface;
  17. class BannedIpRepository extends Repository
  18. {
  19. public function model()
  20. {
  21. return BannedIpModel::class;
  22. }
  23. /**
  24. * 是否禁用IP
  25. * @param $ip
  26. * @return bool
  27. */
  28. public function isBanned($ip)
  29. {
  30. $ip = trim($ip);
  31. return BannedIpModel::query()->where(['ip' => $ip])->exists();
  32. }
  33. /**
  34. * 禁止1个IP.
  35. * @param $ip
  36. * @return \Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model
  37. */
  38. public function doBan($ip)
  39. {
  40. $ip = trim($ip);
  41. return BannedIpModel::query()->create(['ip' => $ip]);
  42. }
  43. /**
  44. * 删除一个IP
  45. * @param $ip
  46. * @return false|int|mixed
  47. */
  48. public function deleteOne($ip)
  49. {
  50. $ip = trim($ip);
  51. return BannedIpModel::query()->where(['ip' => $ip])->take(1)->delete();
  52. }
  53. /**
  54. * 检查黑名单规则.
  55. * @param $ip
  56. * @param array $params
  57. * @return bool
  58. */
  59. public function checkBlackRule($ip, $params = [])
  60. {
  61. $ip = trim($ip);
  62. $cacheRepo = make(Redis::class);
  63. $cacheKey = env('SERVER_CACHE_PREFIX', '') . 'user_ip_check';
  64. $ipValue = $cacheRepo->hget($cacheKey, $ip);
  65. $nowDateObj = Carbon::now();
  66. $isNeedCheck = false; // 默认不检查.
  67. if (!empty($ipValue)) {
  68. // 有值,还需要查看值是否是是当天日期.
  69. $ipNextCheckDateObj = Carbon::parse($ipValue);
  70. if ($ipNextCheckDateObj < $nowDateObj) {
  71. // 下次检查时间小于当前时间,则需要执行检查.
  72. $isNeedCheck = true;
  73. }
  74. } else {
  75. $isNeedCheck = true;
  76. }
  77. if ($isNeedCheck) {
  78. $redNum = 25; // 相同IP,当日注册红线数量.
  79. $startDateObj = Carbon::now()->startOfDay();
  80. $endDateObj = Carbon::now()->endOfDay();
  81. // $startDateObj = Carbon::now()->subMinutes(5);
  82. // $endDateObj = Carbon::now();
  83. // 统计今天时间段内,相同IP,注册用户数量
  84. $countIpUsers = UserModel::query()->where(['ip' => $ip])
  85. ->whereBetween('created_at', [$startDateObj, $endDateObj])
  86. ->orderByDesc('id')
  87. ->count('id');
  88. if ($countIpUsers >= $redNum) {
  89. // 超过红线,执行禁止IP操作,下次一同一个IP无法注册.
  90. if (!$this->isBanned($ip)) {
  91. $this->doBan($ip);
  92. }
  93. }
  94. $nextCheckDateObj = Carbon::now()->addMinutes(5);
  95. $nextCheckDate = $nextCheckDateObj->toDateTimeString();
  96. $cacheRepo->hset($cacheKey, $ip, $nextCheckDate); // 设置下次检查时间.
  97. }
  98. return true;
  99. }
  100. /**
  101. * 清空IP.
  102. */
  103. public function clearAllIp()
  104. {
  105. BannedIpModel::query()->truncate();
  106. }
  107. }