IpFilter.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  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. $request = Yii::$app->request;
  23. $getParams = Yii::$app->request->get();
  24. $postParams = Yii::$app->request->post();
  25. $remoteAddr = $_SERVER['REMOTE_ADDR']; // 获取用户 IP 地址
  26. // 登录接口不需要验证
  27. if (!self::remoteAddrCall($remoteAddr)) {
  28. Yii::warning('GET 参数: ' . json_encode(is_array($getParams) ? $getParams : [], JSON_PRETTY_PRINT), __METHOD__);
  29. Yii::warning('POST 参数: ' . json_encode(is_array($postParams) ? $getParams : [], JSON_PRETTY_PRINT), __METHOD__);
  30. throw new BadRequestHttpException('用户名或者密码错误');
  31. }
  32. }
  33. /**
  34. * @throws AddressNotFoundException
  35. * @throws InvalidDatabaseException
  36. */
  37. public static function remoteAddrCall($remoteAddr): bool
  38. {
  39. // 是否有效的IP
  40. if (!filter_var($remoteAddr, FILTER_VALIDATE_IP)) {
  41. return false;
  42. }
  43. // 替换为 GeoLite2 数据库文件的实际路径
  44. $dbPath = \Yii::getAlias('@common/runtime/geoLite//GeoLite2-Country.mmdb');
  45. // 初始化 MaxMind 数据库读取器
  46. $reader = new \GeoIp2\Database\Reader($dbPath);
  47. // 查询 IP 地址的地理位置
  48. $record = $reader->country($remoteAddr);
  49. // 返回国家名称
  50. $countryName = $record->country->name;
  51. if (!in_array($countryName, ['China'])) {
  52. return false;
  53. }
  54. return true;
  55. }
  56. }