PHPackages                             bespredel/geo-restrict - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. bespredel/geo-restrict

ActiveLibrary[Security](/categories/security)

bespredel/geo-restrict
======================

Middleware to restrict access to Laravel applications based on IP geolocation.

v1.3.3(3mo ago)116MITPHPPHP &gt;=8.1CI passing

Since Jun 24Pushed 3mo agoCompare

[ Source](https://github.com/BespredeL/geo-restrict)[ Packagist](https://packagist.org/packages/bespredel/geo-restrict)[ RSS](/packages/bespredel-geo-restrict/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (13)Used By (0)

GeoRestrict Middleware for Laravel
==================================

[](#georestrict-middleware-for-laravel)

[![Readme EN](https://camo.githubusercontent.com/2e56ca214ef4d8d00bb5d7aa4ec232fc666ccba95fab518ecc19ef1c0aeaa1d6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f524541444d452d454e2d626c75652e737667)](https://github.com/BespredeL/geo-restrict/blob/master/README.md)[![Readme RU](https://camo.githubusercontent.com/9cc74b00b88d39864ca5656899377d910ba6cc1474e523d99f254eea0f1f6fd5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f524541444d452d52552d626c75652e737667)](https://github.com/BespredeL/geo-restrict/blob/master/README_RU.md)[![GitHub license](https://camo.githubusercontent.com/c8d21d6e069c319a1600e80cb1f98c211df3911b71f23aac373822690a19128d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d3435386137622e737667)](https://github.com/BespredeL/geo-restrict/blob/master/LICENSE)[![Downloads](https://camo.githubusercontent.com/0cf7e7fbb4abef867a6314572f90d92597dd1efeca6edb9df2a3586b56a78a10/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f62657370726564656c2f67656f2d72657374726963742e737667)](https://packagist.org/packages/bespredel/geo-restrict)

[![Latest Version](https://camo.githubusercontent.com/01551cb2018bdbb33c859e914cbbfd00bf9fa1e34379dc418fb2e3cb5de3b2e5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f62657370726564656c2f47656f52657374726963743f6c6f676f3d676974687562)](https://github.com/BespredeL/geo-restrict/releases)[![Latest Version Packagist](https://camo.githubusercontent.com/221c613bfb7382a6914205a9ea81e88f9c71c44278a62a5e8d2a72720f33cdad/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f62657370726564656c2f67656f2d72657374726963742e7376673f6c6f676f3d7061636b6167697374266c6f676f436f6c6f723d776869746526636f6c6f723d463238443141)](https://packagist.org/packages/bespredel/geo-restrict)[![PHP from Packagist](https://camo.githubusercontent.com/0c639f14b9cafce8b83f1b6146c271943ba9bc1f6a08600081abb63aef3ae9b7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f62657370726564656c2f67656f2d72657374726963742e7376673f6c6f676f3d706870266c6f676f436f6c6f723d776869746526636f6c6f723d373737424234)](https://php.net)[![Laravel Version](https://camo.githubusercontent.com/8c69c1fbc1927fe6fb505dafc30892d853d9b3ec54764dbaa88a1c6ffb03625e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d25334525334431302d4646324432303f6c6f676f3d6c61726176656c)](https://laravel.com)

GeoRestrict is a Laravel middleware that restricts access to your application based on the user's IP geolocation (country, region, ASN, city, ISP, etc).

Features
--------

[](#features)

- Country, region, ASN, city, ISP filtering by IP
- Multiple geo-services support (priority by order)
- Geo response caching (can be disabled)
- Rate limiting for geo service requests
- Flexible allow/deny rules, including callbacks and time-based restrictions
- IP whitelist (local addresses are always allowed)
- Route targeting via patterns and HTTP methods
- Localized error messages (multi-language, easy to extend)
- Different responses per country/rule
- Logging for blocked and allowed requests

Installation
------------

[](#installation)

1. Install the package:

```
composer require bespredel/geo-restrict
```

2. Publish the configuration:

```
php artisan vendor:publish --provider="Bespredel\GeoRestrict\GeoRestrictServiceProvider" --tag=geo-restrict-config
```

3. (Optional) Publish language files for customization:

```
php artisan vendor:publish --provider="Bespredel\GeoRestrict\GeoRestrictServiceProvider" --tag=geo-restrict-lang
```

Example config `config/geo-restrict.php`
----------------------------------------

[](#example-config-configgeo-restrictphp)

```
return [
    'services' => [
        // Example provider with options
        [
            'provider' => \Bespredel\GeoRestrict\Providers\Ip2LocationIoProvider::class,
            'options'  => [
                'api_key' => 'your-ip2location-api-key', // required
                'lang'    => 'en', // optional
            ],
        ],

        // Example provider without options
        \Bespredel\GeoRestrict\Providers\IpWhoIsProvider::class,

        // or
        [
            'provider' => \Bespredel\GeoRestrict\Providers\IpWhoIsProvider::class,
            'options'  => [],
        ],

        // Example array provider
        [
            'name' => 'ipapi.co',
            'url'  => 'https://ipapi.co/:ip/json/',
            'headers' => [
                'Accept' => 'application/json',
            ],
            'map'  => [
                'country' => 'country_code',
                'region'  => 'region_code',
                'city'    => 'city',
                'asn'     => 'asn',
                'isp'     => 'org',
            ],
        ],

        // Add more services; priority is based on order
    ],

    'geo_services' => [
        'cache_ttl'  => 1440,
        'rate_limit' => 30,
    ],

    'access' => [
        'rules' => [
            'allow' => [
                'country'  => ['RU'],
                'region'   => [],
                'city'     => [],
                'asn'      => [],
                'callback' => null, // function($geo) { return ...; }
                'time'     => [
                    // ['from' => '08:00', 'to' => '20:00']
                ],
            ],
            'deny'  => [
                'country'  => [],
                'region'   => [],
                'city'     => [],
                'asn'      => [],
                'callback' => null, // function($geo) { return ...; }
                'time'     => [
                    // ['from' => '22:00', 'to' => '06:00']
                ],
            ],
        ],
    ],

    'routes' => [
        'only'    => [], // ['admin/*', 'api/v1/*']
        'except'  => [],
        'methods' => [], // ['GET', 'POST']
    ],

    'excluded_networks' => [
        '127.0.0.1',
        '::1',
        '10.0.0.0/8',
        '192.168.0.0/16',
        '172.16.0.0/12',
        // Add more as needed
    ],

    'logging' => [
        'blocked_requests' => true,
        'allowed_requests' => false,
        'channel' => 'geo-restrict', // Use your custom channel name
    ],

    'block_response' => [
        'type'  => 'abort', // 'abort', 'json', 'view'
        'view'  => 'errors.geo_blocked',
        'json'  => [
            'message' => 'Access denied: your region is restricted.',
        ],
    ]
];
```

### Key parameters explained

[](#key-parameters-explained)

- **services** - list of geo-services used to resolve location by IP. Each provider supports only its documented parameters (see table below).
- **geo\_services.cache\_ttl** - cache lifetime in minutes (0 disables caching).
- **geo\_services.rate\_limit** - max requests per minute per IP to geo services.
- **access.rules.allow/deny** - allow/deny rules by country, region, ASN, callbacks and time periods.
- **logging** - enable logging of blocked or allowed requests.
- **block\_response.type** - response type: 'abort', 'json', or 'view'.
- **routes.only/except/methods** - route and method matching.
- **excluded\_networks** - list of IP networks to exclude from geo restriction.

#### Supported Providers and Parameters

[](#supported-providers-and-parameters)

ProviderClassRequired ParamsOptional ParamsIP2Location.ioIp2LocationIoProviderapi\_key, iplangipwho.isIpWhoIsProvideripapi\_keyip-api.comIpApiComProvideriplangipapi.coIpApiCoProvideriplangOnly parameters listed in `requiredParams` and `optionalParams` for each provider will be used in the request. If a required parameter is missing, an error will be thrown and logged. Optional parameters are included only if set in config.

---

### Provider architecture

[](#provider-architecture)

All geo providers now inherit from `AbstractGeoProvider` and only need to define:

- `baseUrl`, `endpoint` (with :param placeholders)
- `requiredParams`, `optionalParams`
- `responseMap` (array for mapping API fields to standard keys)
- `isValidResponse(array $data)` (checks if API response is valid)
- `getErrorMessage(array $data)` (returns error message for invalid response)

**Example of a minimal provider:**

```
class ExampleProvider extends AbstractGeoProvider {
    protected ?string $baseUrl = 'https://example.com/';
    protected ?string $endpoint = 'api/:ip';
    protected array $requiredParams = ['ip'];
    protected array $optionalParams = ['lang'];
    protected array $responseMap = [
        'country' => 'country_code',
        'region'  => 'region',
        'city'    => 'city',
        'asn'     => 'asn',
        'isp'     => 'isp',
    ];
    protected function isValidResponse(array $data): bool {
        return isset($data['country_code']);
    }
    protected function getErrorMessage(array $data): string {
        return 'example.com: invalid response';
    }
    public function getName(): string { return 'example.com'; }
}
```

This makes it easy to add new providers and ensures all logic is unified and DRY.

Usage
-----

[](#usage)

1. Add the middleware to routes:

```
Route::middleware(['geo-restrict'])->group(function () {
    // ...
});
```

2. Or apply directly:

```
Route::get('/secret', 'SecretController@index')->middleware('geo-restrict');
```

Customization
-------------

[](#customization)

- Add your geo-services to the `services` array; order defines priority.
- Use allow/deny rules for flexible filtering.
- For complex cases, use callback functions in rules.
- For localization, use language files.

Localization and Language Files
-------------------------------

[](#localization-and-language-files)

GeoRestrict supports multi-language block messages. To customize or add new translations:

1. Publish the language files:

```
php artisan vendor:publish --provider="Bespredel\GeoRestrict\GeoRestrictServiceProvider" --tag=geo-restrict-lang
```

2. Edit files in `resources/lang/vendor/geo-restrict/` as needed. Add new locales by creating new folders (e.g., `it`, `es`).

- The block message is automatically shown in the user's country language (based on the country code, if a corresponding language file exists), or in the application's default language.
- To add a new language, create a file like:

```
resources/lang/it/messages.php

```

No code changes are required - the language is detected automatically based on the country code (e.g., IT, FR, DE, RU, EN, etc.).

Cache Management &amp; Tag-based Cache Flush
--------------------------------------------

[](#cache-management--tag-based-cache-flush)

GeoRestrict uses Laravel's cache for geo-data and rate limiting. If your cache driver supports tags (Redis, Memcached), all geoip cache entries are tagged with `geoip`.

- To flush all geoip cache entries at once, use the artisan command:

```
php artisan geo-restrict:clear-cache
```

You will see:

```
GeoIP cache flushed.

```

> **Note:** Tag-based cache flush is only available for Redis and Memcached drivers. For other drivers, cache will not be flushed in bulk.

Logging: Custom Channel Support
-------------------------------

[](#logging-custom-channel-support)

GeoRestrict supports logging to a custom channel. By default, all logs (blocked/allowed requests, provider errors, rate limits) go to the main Laravel log. To use a separate channel, set the `logging.channel` parameter in your `config/geo-restrict.php`:

```
'logging' => [
    'blocked_requests' => true,
    'allowed_requests' => false,
    'channel' => 'geo-restrict', // Use your custom channel name
],
```

Add a channel to your `config/logging.php`:

```
'channels' => [
    // ...
    'geo-restrict' => [
        'driver' => 'single',
        'path' => storage_path('logs/geo-restrict.log'),
        'level' => 'info',
    ],
],
```

If `channel` is not set or is `null`, logs will go to the default log channel.

License
-------

[](#license)

This package is open-source software licensed under the MIT license.

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance82

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Recently: every ~43 days

Total

11

Last Release

91d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9eef72f851d43a1dfcd242a67bcec5667b85196ffa60438381e84be38a3ff912?d=identicon)[BespredeL](/maintainers/BespredeL)

---

Top Contributors

[![BespredeL](https://avatars.githubusercontent.com/u/3052150?v=4)](https://github.com/BespredeL "BespredeL (59 commits)")

---

Tags

accessgeogeoipiplaravellocationmiddlewarerestrictionmiddlewarelaravelgeoipaccessIPlocationgeorestriction

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/bespredel-geo-restrict/health.svg)

```
[![Health](https://phpackages.com/badges/bespredel-geo-restrict/health.svg)](https://phpackages.com/packages/bespredel-geo-restrict)
```

###  Alternatives

[stevebauman/location

Retrieve a user's location by their IP Address

1.3k7.6M65](/packages/stevebauman-location)[hibit-dev/geodetect

Automatically detect user's geo data based on their IP address

2319.5k](/packages/hibit-dev-geodetect)[interaction-design-foundation/laravel-geoip

Support for multiple Geographical Location services.

17221.0k3](/packages/interaction-design-foundation-laravel-geoip)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
