xorgxx / neox-geolocator-bundle
Neox 地理定位组件包,适用于 Symfony
0.6.4
2023-12-14 09:37 UTC
Requires
- php: >=8.1
- symfony/config: ^6.3||^6.4||^7.0
- symfony/dependency-injection: ^6.3||^6.4||^7.0
- symfony/deprecation-contracts: ^2.2|^3
- symfony/framework-bundle: ^6.3||^6.4||^7.0
- symfony/http-client: ^6.3||^6.4||^7.0
- symfony/http-kernel: ^6.3||^6.4||^7.0
Requires (Dev)
- symfony/phpunit-bridge: ^6.3||^6.4||^7.0
- symfony/security-core: ^6.3||^6.4||^7.0
- symfony/yaml: ^6.3||^6.4||^7.0
This package is auto-updated.
Last update: 2024-09-25 07:59:46 UTC
README
本组件包提供额外的地理定位工具,旨在简化您在应用中管理这些工具的过程,并作为防火墙使用!
假设您不希望来自“南美洲”的用户访问您的应用,或者不希望使用 Vpn、代理、Tor 的用户访问,或者您只想允许来自“巴黎”的用户访问。地理定位正是您需要的解决方案!即使无法过滤移动设备,如果所有过滤条件都返回“Seo_unauthorized”,则不会允许访问您的网站。
BETA 版本安装!!
使用 Composer 安装组件包,因为它目前处于 beta 版本!!
composer require xorgxx/neox-geolocator-bundle
or
composer require xorgxx/neox-geolocator-bundle:0.*
确保在您的 AppKernel 中注册了组件包
Bundles.php <?php return [ ..... NeoxGeolocator\NeoxGeolocatorBundle\NeoxGeolocatorBundle::class => ['all' => true], ..... ];
注意: 您可能需要使用 [symfony composer dump-autoload] 来重新加载自动加载
..... 完成 🎈
配置
- 安装和配置 ==> Symfony 配置
- 在配置文件夹中创建 neox_geolocator.yaml
└─── config
│ └─── packages
│ └─── neox_geolocator.yaml
| └─── .....
neox_seo.yaml
自动设置,但您可以自定义(默认)
neox_geolocator:
ip_local_dev: "156.146.55.226" # for test Bulgary "156.146.55.226"
forcer: false # this is to force to get new geolocator same timer it's userfull.
check_ping: # false | true it will protect agains "death ping" !!!
on: false # on off
expire: 10 # check expiration to reste timer
ping: 5 # after x ping on "expire" value it will banni for xxx
banni: 700 # in seconde banni time
cdn:
api_use: "findip.net" # ip-api.com freemium, check.getipintel.net FREE, https://findip.net/ free
api_key: "xxxxxxxxxxxxxxxxxx"
filter:
# Local how can in website | rule order read = 1
local:
- 'FR'
- 'BG'
# Continents how can in website | rule order read = 2
continents:
- "Europe"
- "North America"
# - "South America"
# - "Asia"
# Connection how cant in website !!! | rule order read = 3
connection:
- "vpn"
- "proxy"
# Crawler how can in website !! | rule order read = 4
crawler:
- "Googlebot"
- "Bingbot"
- "YandexBot"
- "AppleBot"
- "DuckDuckBot"
- "BaiduSpider"
- "SpiderSogou"
- "FacebookExternalHit"
- "Exabot"
- "Swiftbot"
- "SlurpBot"
- "CCBot"
- "GoogleOther"
- "Google-InspectionTool"
name_route_exclude: # all this name-route will be excluded form the geolocator !!!
- "Seo_unauthorized"
- "app_home_profile_crud_alert"
name_route_unauthorized: "Seo_unauthorized"
timer: 10
check_vpn: "seo_check_vpn" >>> name route to redirect when detect no id session yet
如何使用?
- 非常简单!
- 请注意,我使用 Redis 存储会话信息,这可能会对您的应用产生影响。
- 缓存系统,设置 expirAfter 确保键在 xx 后过期,并强制再次控制。
只需创建路由和模板到 name_route_unauthorized: "Seo_unauthorized"
/** * @Route("/unauthorized", name="Seo_unauthorized") * @param Request $request * @return Response */ #[NeoxGeoBag( forcer: true, filterLocal: ["RU", "GB"], filterContinents: ["Asia"])] public function unauthorized(Request $request, CacheItemPoolInterface $adapter): Response { $session = $request->getSession(); $Geolocator = $adapter->getItem(geolocatorAbstract::NAME . $session->getId()); $metadata = $Geolocator->getMetadata(); if ( $Geolocator && $Geolocator->isHit() && array_key_exists('expiry', $metadata)) { $expirationTimestamp = $metadata['expiry']; $expirationDateTime = $date = new DateTime("@$expirationTimestamp"); }; $i = $Geolocator->get("value"); return $this->render('unauthorized.html.twig', [ "Geolocator" => $Geolocator->get("value"), "timer" => $expirationDateTime ?? null, ]); }
{% block HEADERSLIDER %} <section id="slider" class="slider-element min-vh-100 page-section slide-img include-header" data-animate="img-to-right" style="background: url('{{ imgErrorBackg }}') center center no-repeat; background-size: cover;"> <div class="slider-inner"> <div class="vertical-middle"> <div class="container-fluid clearfix vertical-middle" style="z-index: 6"> <div class="heading-block center topmargin nobottomborder"> {% if Geolocator is not null %} <i style="line-height:unset !important;" class="fa-2xl fi fi-{{ Geolocator.countryCode|lower == 'en' ? 'gb' : Geolocator.countryCode|lower }}"></i> {% if Geolocator.valid %} <h1>{{ 'unauthorized.title'|trans }} </h1> <span><i class="{{ Geolocator.valid ? 'text-success' : 'text-danger' }} fa-solid {{ Geolocator.valid ? 'fa-check-square' : 'fa-window-close' }}"></i> <strong>{{ Geolocator.country }}</strong>, {{ Geolocator.city }}</span> {% else %} <h1>{{ 'unauthorized.fail.title'|trans }} </h1> <span><i class="{{ Geolocator.valid ? 'text-success' : 'text-danger' }} fa-solid {{ Geolocator.valid ? 'fa-check-square' : 'fa-window-close' }}"></i> <strong>{{ Geolocator.country }}</strong>, {{ Geolocator.city }}</span> {% if Geolocator.proxy|default(0) %} <span><i class="{{ Geolocator.proxy|default(0) ? 'text-danger' : 'text-success' }} fa-solid {{ Geolocator.proxy|default(0) ? 'fa-window-close' : 'fa-check-square' }}"></i> Proxy / Vpn / Tor : {{ Geolocator.proxy|default(0) ? 'Detecté !' : ' - ' }}</span> {% endif %} <span>{{ 'unauthorized.fail.subtitle'|trans }}</span> <div class="row justify-content-center col-mb-50"> <div class="col-sm-6 col-lg-4"> </div> <div class="col-sm-6 col-lg-4"> <div class="feature-box fbox-center fbox-light fbox-plain"> <div class="fbox-icon"> <a href="#"><i class="icon-time"></i></a> </div> <div class="fbox-content"> <h3>{{ 'unauthorized.title-time'|trans |raw }}</h3> <p>{{ 'unauthorized.subtitle-time'|trans |raw }}</p> </div> </div> </div> </div> {% endif %} <small>- {{ timer|format_datetime('short', timezone='Europe/Paris') }} -</small> {% else %} <span><i class="text-danger fa-solid fa-window-close"></i> Proxy / Vpn / Tor : Detecté !</span> {% endif %} </div> </div> </div> </div> </section> {% endblock %}
示例:twig check_vpn
..... {% block javascripts %} <script> // Wait 0.5 seconds (500 milliseconds) then redirect setTimeout(function() { window.location.href = "/"; }, 500); </script> {% endblock %}
高级用法
- 您有自己的地理位置服务提供商?没问题
neox_geolocator:
....
custome_api: app\services\IpApiService # path to your file
....
此文件具有以下结构
namespace App\Services; use NeoxGeolocator\NeoxGeolocatorBundle\Entity\Geolocation; use NeoxGeolocator\NeoxGeolocatorBundle\Pattern\geolocatorAbstract; use NeoxGeolocator\NeoxGeolocatorBundle\Pattern\GeolocatorInterface; use Psr\Cache\InvalidArgumentException; use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\CacheItem; use Symfony\Contracts\Cache\ItemInterface; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; class ipApiService extends geolocatorAbstract implements GeolocatorInterface { public function Geolocator(): Geolocation { // get geolocation $this->Geolocation = $this->getInfoCdn(); // set filter Local $this->setFilterLocal(); // set filter contement $this->setFilterContinents(); // set filter Connection $this->setFilterConnection(); // set crawler $this->setFilterCrawler(); // $this->requestStack->getSession()->set('geolocator', $this->Geolocation); return $this->Geolocation; // TODO: Implement Geolocator() method. } public function getInfoCdn(): Geolocation{ // check ip // $currentIp = $ipCheck ?: $this->httpClient->request('GET', $this->CDN["ip"] )->getContent(); // $currentIp = $this->requestStack->getCurrentRequest()->getClientIp(); $data = ""; if ( $this->getLimiter('ipapi') ) { $currentIp = $this->getRealIp(); $api = "http://" . $this->neoxBag->getCdn()["api_use"] . "/json/$currentIp?fields=status,message,continent,continentCode,country,countryCode,regionName,city,zip,lat,lon,reverse,mobile,proxy,hosting,query"; // todo: check if this expires !!! $response_ = $this->httpClient->request('GET', $api ); $data = $response_->getContent(); # for adaptation data 2 options # FIRST OPTION return Geolocation::fromJson($data); # SECOND OPTION $geolocation = new Geolocation(); $geolocationModel->setstatus('success') // = ; ->setcontinent($o["continent"]["names"]["fr"]) // = 'Europe'; ->setcontinentCode($o["continent"]["code"]) // = 'EU'; ->setcountry($o["country"]["names"]["en"]) // = 'France'; ->setcountryCode($o["country"]["iso_code"]) // = 'FR'; ->setregionName($o["subdivisions"][0]["names"]["en"]) // = 'Paris'; ->setcity($o["city"]["names"]["en"]) // = 'Paris'; ->setzip($o["postal"]["code"]) // = '75000'; ->setlat($o["location"]["latitude"]) // = 40.6951; ->setlon($o["location"]["longitude"]) // = 20.325; ->setreverse($o["traits"]["isp"]) // = 'unn-156-146-55-226.cdn'; ->setmobile('nc') // = false; ->setproxy(($o["traits"]["connection_type"] == 'Corporate' ? true : false)) // = false; ->sethosting(($o["traits"]["user_type"] == 'hosting' ? true : false)) // = false; ->setquery($currentIp) // = '156.146.55.226'; ->setvalid(true) // = true; ; return $geolocation; }else{ /** @var geolocatorAbstract $class */ $class = $this->buildClass("findIpService"); return $class->Geolocator(); } } }
-
在 3 个事件上添加事件监听器
const NEOX_GEOLOCATOR_EVENT = 'neox.geolocator.event'; const NEOX_GEOLOCATOR_PASS = 'neox.geolocator.pass'; const NEOX_GEOLOCATOR_FAIL = 'neox.geolocator.fail';
因此现在您可以在您的应用中创建自己的统计方法!在 App\EventSubscriber 中
<?php namespace App\EventSubscriber; use NeoxGeolocator\NeoxGeolocatorBundle\Event\NeoxGeolocatorEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class NeoxGeolocatorSubscriber implements EventSubscriberInterface { /** * @inheritDoc */ public static function getSubscribedEvents(): array { return [ NeoxGeolocatorEvents::NEOX_GEOLOCATOR_EVENT => 'onCustomEvent', NeoxGeolocatorEvents::NEOX_GEOLOCATOR_PASS => 'onCustomEvent', NeoxGeolocatorEvents::NEOX_GEOLOCATOR_FAIL => 'onCustomEvent', ]; } public function onCustomEvent(NeoxGeolocatorEvents $event): void { // Faire quelque chose avec l'événement $neoxGeolocation = $event->getGeolocation(); ...... } }
工具!
贡献
如果您想为此组件包做出贡献(感谢您!)请参考以下指南
- 请遵守 Symfony 指南
- 测试一切!请在上传测试案例到 tests/ 目录时
- 修复了一个之前未涵盖的 bug
- 注解!!
待办事项
- Packagist