IpFilter.php 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  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. if (!self::remoteAddrCall($remoteAddr)) {
  24. throw new BadRequestHttpException('非法 IP 地址');
  25. }
  26. }
  27. /**
  28. * @throws AddressNotFoundException
  29. * @throws InvalidDatabaseException
  30. */
  31. public static function remoteAddrCall($remoteAddr): bool
  32. {
  33. // 是否有效的IP
  34. if (!filter_var($remoteAddr, FILTER_VALIDATE_IP)) {
  35. return false;
  36. }
  37. // 替换为 GeoLite2 数据库文件的实际路径
  38. $dbPath = \Yii::getAlias('@common/runtime/geoLite//GeoLite2-Country.mmdb');
  39. // 初始化 MaxMind 数据库读取器
  40. $reader = new \GeoIp2\Database\Reader($dbPath);
  41. // 查询 IP 地址的地理位置
  42. $record = $reader->country($remoteAddr);
  43. // 返回国家名称
  44. $countryName = $record->country->name;
  45. if (!in_array($countryName, ['China'])) {
  46. return false;
  47. }
  48. return true;
  49. }
  50. }