|
|
@@ -0,0 +1,58 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace common\libs;
|
|
|
+
|
|
|
+use Yii;
|
|
|
+use yii\base\Component;
|
|
|
+use yii\web\BadRequestHttpException;
|
|
|
+use yii\web\Application;
|
|
|
+use MaxMind\Db\Reader;
|
|
|
+use MaxMind\Db\InvalidDatabaseException;
|
|
|
+use MaxMind\Db\AddressNotFoundException;
|
|
|
+class IpFilter extends Component
|
|
|
+{
|
|
|
+ public function init()
|
|
|
+ {
|
|
|
+ parent::init();
|
|
|
+ Yii::$app->on(Application::EVENT_BEFORE_REQUEST, [$this, 'checkIp']);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @throws BadRequestHttpException
|
|
|
+ */
|
|
|
+ public function checkIp()
|
|
|
+ {
|
|
|
+ $request = Yii::$app->getRequest();
|
|
|
+ $remoteAddr = $request->getUserIP(); // 获取用户 IP 地址
|
|
|
+
|
|
|
+ if (!self::remoteAddrCall($remoteAddr)) {
|
|
|
+ throw new BadRequestHttpException('非法 IP 地址');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @throws AddressNotFoundException
|
|
|
+ * @throws InvalidDatabaseException
|
|
|
+ */
|
|
|
+ public static function remoteAddrCall($remoteAddr): bool
|
|
|
+ {
|
|
|
+ // 是否有效的IP
|
|
|
+ if (!filter_var($remoteAddr, FILTER_VALIDATE_IP)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 替换为 GeoLite2 数据库文件的实际路径
|
|
|
+ $dbPath = \Yii::getAlias('@common/runtime/geoLite//GeoLite2-Country.mmdb');
|
|
|
+ // 初始化 MaxMind 数据库读取器
|
|
|
+ $reader = new \GeoIp2\Database\Reader($dbPath);
|
|
|
+ // 查询 IP 地址的地理位置
|
|
|
+ $record = $reader->country($remoteAddr);
|
|
|
+ // 返回国家名称
|
|
|
+ $countryName = $record->country->name;
|
|
|
+ if (!in_array($countryName, ['China'])) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|