it-roy-ru.com

Как получить IP-адрес клиента в Laravel 5+?

Я пытаюсь получить IP-адрес клиента в Laravel. Поскольку все мы знаем, что получить IP-адрес клиента в PHP намного проще, используя $_SERVER["REMOTE_ADDR"].

В ядре PHP он работает нормально, но когда я использую то же самое в Laravel, он дает IP-адрес сервера вместо IP-адреса посетителя.

91
Amrinder Singh

Глядя на Laravel API :

Request::ip();

Внутренне он использует метод getClientIps из объекта запроса Symfony :

public function getClientIps()
{
    $clientIps = array();
    $ip = $this->server->get('REMOTE_ADDR');
    if (!$this->isFromTrustedProxy()) {
        return array($ip);
    }
    if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) {
        $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]);
        preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches);
        $clientIps = $matches[3];
    } elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
        $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
    }
    $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
    $ip = $clientIps[0]; // Fallback to this when the client IP falls into the range of trusted proxies
    foreach ($clientIps as $key => $clientIp) {
        // Remove port (unfortunately, it does happen)
        if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) {
            $clientIps[$key] = $clientIp = $match[1];
        }
        if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
            unset($clientIps[$key]);
        }
    }
    // Now the IP chain contains only untrusted proxies and the client IP
    return $clientIps ? array_reverse($clientIps) : array($ip);
} 
125
samlev

Используйте request()->ip() 

Начиная с Laravel 5 (насколько я понимаю) рекомендуется/хорошая практика использовать глобальные функции, такие как: 

response()->json($v);
view('path.to.blade');
redirect();
route();
cookie();

Вы понимаете :-) И, если что, при использовании функций (вместо статического нотариуса) мой IDE не горит как рождественская елка ;-)

51
Stan Smulders

Если вы находитесь под балансировщиком нагрузки

\Request::ip()всегда Laravel возвращает IP-адрес балансировщика

            echo $request->ip();
            // server ip

            echo \Request::ip();
            // server ip

            echo \request()->ip();
            // server ip

            echo $this->getIp(); //see the method below
            // clent ip

Этот пользовательский метод возвращает реальный IP-адрес клиента:

public function getIp(){
    foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
        if (array_key_exists($key, $_SERVER) === true){
            foreach (explode(',', $_SERVER[$key]) as $ip){
                $ip = trim($ip); // just to be safe
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                    return $ip;
                }
            }
        }
    }
}

Подробнее: Если вы используете промежуточное программное обеспечение дросселя Laravel

В дополнение к этому, я предлагаю вам быть очень осторожным, используя промежуточное ПО Laravel throttle: оно также использует функцию Request::ip() Laravel, поэтому все ваши посетители будут идентифицированы как один и тот же пользователь, и вы очень быстро достигнете предела газа. Опыт в жизни ... это привело меня к большим проблемам ...

Чтобы исправить это:

Осветить\Http\Request.php

    public function ip()
    {
        //return $this->getClientIp(); //original method
        return $this->getIp(); // the above method
    }

Теперь вы также можете использовать функцию Request::ip(), которая должна возвращать реальный IP-адрес в процессе производства.

46
Sebastien Horin

Добавить пространство имен 

use Request;

Затем вызовите функцию 

Request::ip();
22
shalini

Для Laravel 5 вы можете использовать объект Request. Просто вызовите его метод ip (). Что-то вроде:

$request->ip();

12
TodStoychev

В Ларавеле 5

public function index(Request $request) {
  $request->ip();
}
9
Govind Samrow

в версии laravel 5.4 мы не можем назвать ip static это правильный способ получить IP-пользователя 

 use Illuminate\Http\Request;

public function contactUS(Request $request)
    {
        echo $request->ip();
        return view('page.contactUS');
    }
2
Vahid Alvandi

Если вам нужен IP-адрес клиента, а ваш сервер находится за aws elb, то используйте следующий код. Протестировано на Laravel 5.3

$elbSubnet = '172.31.0.0/16';
Request::setTrustedProxies([$elbSubnet]);
$clientIp = $request->ip();
2
Aung Bo

Есть 2 вещи, о которых нужно позаботиться

1) получить вспомогательную функцию, которая возвращает Illuminate\Http\Request и вызывает ->ip() метод.

request()->ip();

2) Подумайте о конфигурации вашего сервера, он может использовать proxy или load balancer (особенно в AWS ELB config)

Если это ваш случай, вам нужно Настройка доверенных прокси или, возможно, даже установить опцию Trusting All Proxies.

Зачем?

Потому что, будучи вашим сервером, вы получите ваш IP прокси/балансировщика.

Как?

Если вы не AWS balance-loader

Перейти к App\Http\Middleware\TrustProxies

и сделать объявление $proxies следующим образом:

protected $proxies = '*';

Теперь проверьте это и будьте счастливы, потому что вы только что избавили себя от проблем с throttle middleware. Он также полагается на request()->ip() и без настройки TrustProxies вы можете запретить всем пользователям вход в систему вместо блокировки только IP-адреса виновного.

И поскольку throttle middleware не объяснено должным образом в документации, я рекомендую посмотреть это видео

Протестировано в Laravel 5.7

1
Yevgeniy Afanasyev

Если вы все еще получаете 127.0.0.1 в качестве IP-адреса, вам нужно добавить свой «прокси». 

Но будьте осторожны, что вы должны изменить его перед началом производства!

Прочитайте эту часть: https://laravel.com/docs/5.7/requests#configuring-trusted-proxies

А теперь просто добавьте это:

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies = '*';

Теперь request () -> ip () дает вам правильный ip

1
Shadrix

Если вы вызываете эту функцию, вы легко получаете IP-адрес клиента . Я уже использовал этот полезный код в моем существующем проекте.

public function getUserIpAddr(){
       $ipaddress = '';
       if (isset($_SERVER['HTTP_CLIENT_IP']))
           $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
       else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
           $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
       else if(isset($_SERVER['HTTP_X_FORWARDED']))
           $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
       else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
           $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
       else if(isset($_SERVER['HTTP_FORWARDED']))
           $ipaddress = $_SERVER['HTTP_FORWARDED'];
       else if(isset($_SERVER['REMOTE_ADDR']))
           $ipaddress = $_SERVER['REMOTE_ADDR'];
       else
           $ipaddress = 'UNKNOWN';    
       return $ipaddress;
    }
0
Soura Sankar Ghosh