IpFilter.php 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. use common\helpers\LoggerTool;
  11. class IpFilter
  12. {
  13. /**
  14. * @throws BadRequestHttpException
  15. * @return bool
  16. */
  17. public function checkIp($source, $isLogin = false): bool
  18. {
  19. $request = Yii::$app->request;
  20. $getParams = Yii::$app->request->get();
  21. $postParams = Yii::$app->request->post();
  22. $ip = $_SERVER['REMOTE_ADDR']; // 获取用户 IP 地址
  23. //如果IP不在指定范围内
  24. if (!self::checkIpInAllowRange($ip)) {
  25. $logPreix = $isLogin ? 'nc_ip_filter_login' : 'nc_ip_filter_other';
  26. $getLog = sprintf('%s_%s: remote_ip%s: url(%s): param%s', $source, $logPreix, $ip, $request->getAbsoluteUrl(), (is_array($getParams) ? json_encode($getParams) : $getParams));
  27. $postLog = sprintf('%s_%s: remote_ip%s: url(%s): param%s', $source, $logPreix, $ip, $request->getAbsoluteUrl(), (is_array($postParams) ? json_encode($postParams) : $postParams));
  28. LoggerTool::error($getLog);
  29. LoggerTool::error($postLog);
  30. return false;
  31. }
  32. return true;
  33. }
  34. /**
  35. * 判断IP是否在指定范围内
  36. * @throws AddressNotFoundException
  37. * @throws InvalidDatabaseException
  38. */
  39. public static function checkIpInAllowRange($ip): bool
  40. {
  41. // 是否有效的IP
  42. if (!filter_var($ip, FILTER_VALIDATE_IP)) {
  43. return false;
  44. }
  45. // 开放跳板机IP,后台快速登录使用
  46. if (in_array($ip, ['8.219.172.88'])) {
  47. return true;
  48. }
  49. // 替换为 GeoLite2 数据库文件的实际路径
  50. $dbPath = \Yii::getAlias('@common/runtime/geoLite//GeoLite2-Country.mmdb');
  51. // 初始化 MaxMind 数据库读取器
  52. $reader = new \GeoIp2\Database\Reader($dbPath);
  53. // 查询 IP 地址的地理位置
  54. $record = $reader->country($ip);
  55. // 返回国家名称
  56. $countryName = $record->country->name;
  57. if (!in_array($countryName, ['China', 'Malaysia'])) {
  58. return false;
  59. }
  60. return true;
  61. }
  62. }