IpFilter.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. <?php
  2. namespace common\libs;
  3. use Yii;
  4. use yii\base\Component;
  5. use yii\web\BadRequestHttpException;
  6. use yii\web\Application;
  7. use MaxMind\Db\Reader;
  8. use MaxMind\Db\InvalidDatabaseException;
  9. use MaxMind\Db\AddressNotFoundException;
  10. class IpFilter extends Component
  11. {
  12. public function init()
  13. {
  14. parent::init();
  15. Yii::$app->on(Application::EVENT_BEFORE_REQUEST, [$this, 'checkIp']);
  16. }
  17. /**
  18. * @throws BadRequestHttpException
  19. */
  20. public function checkIp()
  21. {
  22. $remoteAddr = $_SERVER['REMOTE_ADDR']; // 获取用户 IP 地址
  23. // 调用远程 IP 地址查询方法
  24. if (!self::remoteAddrCall($remoteAddr)) {
  25. throw new BadRequestHttpException('非法 IP 地址');
  26. }
  27. }
  28. /**
  29. * @throws AddressNotFoundException
  30. * @throws InvalidDatabaseException
  31. */
  32. public static function remoteAddrCall($remoteAddr): bool
  33. {
  34. // 是否有效的IP
  35. if (!filter_var($remoteAddr, FILTER_VALIDATE_IP)) {
  36. return false;
  37. }
  38. // 替换为 GeoLite2 数据库文件的实际路径
  39. $dbPath = \Yii::getAlias('@common/runtime/geoLite//GeoLite2-Country.mmdb');
  40. // 初始化 MaxMind 数据库读取器
  41. $reader = new \GeoIp2\Database\Reader($dbPath);
  42. // 查询 IP 地址的地理位置
  43. $record = $reader->country($remoteAddr);
  44. // 返回国家名称
  45. $countryName = $record->country->name;
  46. if (!in_array($countryName, ['China'])) {
  47. return false;
  48. }
  49. return true;
  50. }
  51. }