Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional IP selection handler #39

Merged
merged 13 commits into from
Jul 18, 2022
47 changes: 46 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Default cache TTL and maximum size can be changed by setting values in the `$set

#### Using a different cache

It is possible to use a custom cache by creating a child class of the [CacheInterface](https://github.com/ipinfo/php/blob/master/src/cache/Interface.php) class and setting the the `cache` config value in `\config\services.php`. FYI this is known as [the Strategy Pattern](https://sourcemaking.com/design_patterns/strategy).
It is possible to use a custom cache by creating a child class of the [CacheInterface](https://github.com/ipinfo/php/blob/master/src/cache/CacheInterface.php) class and setting the the `cache` config value in `\config\services.php`. FYI this is known as [the Strategy Pattern](https://sourcemaking.com/design_patterns/strategy).

```php
'ipinfo' => [
Expand All @@ -141,6 +141,51 @@ It is possible to use a custom cache by creating a child class of the [CacheInte
],
```

### IP Selection Mechanism

By default, the IP from the incoming request is used.

Since the desired IP by your system may be in other locations, the IP selection mechanism is configurable and some alternative built-in options are available.

#### Using built-in ip selectors

##### DefaultIPSelector

A [DefaultIPSelector](https://github.com/ipinfo/php/blob/master/src/iphandler/DefaultIPSelector.php) is used by default if no IP selector is provided. It returns the source IP from the incoming request.

This selector can be set explicitly by setting the `ip_selector` config value in `\config\services.php`.

```php
'ipinfo' => [
'ip_selector' => new DefaultIPSelector(),
],
```

##### OriginatingIPSelector

A [OriginatingIPSelector](https://github.com/ipinfo/php/blob/master/src/iphandler/OriginatingIPSelector.php) selects an IP address by trying to extract it from the `X-Forwarded-For` header. This is not always the most reliable unless your proxy setup allows you to trust it. It will default to the source IP on the request if the header doesn't exist.

This selector can be set by setting the `ip_selector` config value in `\config\services.php`.

```php
'ipinfo' => [
'ip_selector' => new OriginatingIPSelector(),
],
```

#### Using a custom IP selector

In case a custom IP selector is required, you may implement the [IPHandlerInterface](https://github.com/ipinfo/php/blob/master/src/iphandler/IPHandlerInterface.php) interface and set the `ip_selector` config value in `\config\services.php`.

For example:

```php
'ipinfo' => [
...
'ip_selector' => new CustomIPSelector(),
],
```

### Internationalization

When looking up an IP address, the response object includes a `$request->ipinfo->country_name` property which includes the country name based on American English. It is possible to return the country name in other languages by telling the library to read from a custom file. To define a custom file, add the following to your app's `\config\services.php` file and replace `{{countries}}` with your own file path.
Expand Down
20 changes: 20 additions & 0 deletions src/iphandler/DefaultIPSelector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace ipinfo\ipinfolaravel\iphandler;

/**
* Implementation of the IPHandlerInterface used as default option. Retrieve IP from request.
*/
class DefaultIPSelector implements IPHandlerInterface
{

/**
* Selects default IP address from request.
* @param \Illuminate\Http\Request $request
* @return string IP address.
*/
public function getIP($request)
{
return $request->ip();
}
}
17 changes: 17 additions & 0 deletions src/iphandler/IPHandlerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace ipinfo\ipinfolaravel\iphandler;

/**
* Interface for handling the mechanism of IP retrieval.
*/
interface IPHandlerInterface
{

/**
* Get IP address.
* @param \Illuminate\Http\Request $request
* @return string IP address.
*/
public function getIP($request);
}
28 changes: 28 additions & 0 deletions src/iphandler/OriginatingIPSelector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace ipinfo\ipinfolaravel\iphandler;

/**
* Selects originating client IP from the request.
*/
class OriginatingIPSelector implements IPHandlerInterface
{

/**
* Selects originating client IP from request.
* @param \Illuminate\Http\Request $request
* @return string IP address.
*/
public function getIP($request)
{
$xForwardedFor = $request->headers->get('x-forwarded-for');
if (empty($xForwardedFor)) {
$ip = $request->ip();
} else {
$ips = explode(',', $xForwardedFor);
// trim as officially the space comes after each comma separator
$ip = trim($ips[0]);
}
return $ip;
}
}
10 changes: 9 additions & 1 deletion src/ipinfolaravel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Closure;
use ipinfo\ipinfo\IPinfo as IPinfoClient;
use ipinfo\ipinfolaravel\DefaultCache;
use ipinfo\ipinfolaravel\iphandler\DefaultIPSelector;

class ipinfolaravel
{
Expand All @@ -26,6 +27,12 @@ class ipinfolaravel
*/
public $filter = null;

/**
* Provides ip.
* @var ipinfo\ipinfolaravel\iphandler\IPHandlerInterface
*/
public $ip_selector = null;

const CACHE_MAXSIZE = 4096;
const CACHE_TTL = 60 * 24;

Expand All @@ -43,7 +50,7 @@ public function handle($request, Closure $next)
$details = null;
} else {
try {
$details = $this->ipinfo->getDetails($request->ip());
$details = $this->ipinfo->getDetails($this->ip_selector->getIP($request));
} catch (\Exception $e) {
$details = null;

Expand All @@ -70,6 +77,7 @@ public function configure()
$this->access_token = config('services.ipinfo.access_token', null);
$this->filter = config('services.ipinfo.filter', [$this, 'defaultFilter']);
$this->no_except = config('services.ipinfo.no_except', false);
$this->ip_selector = config('services.ipinfo.ip_selector', new DefaultIPSelector());

if ($custom_countries = config('services.ipinfo.countries_file', null)) {
$this->settings['countries_file'] = $custom_countries;
Expand Down