Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Глядя на 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);
} 

Ответ 2

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

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

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

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

Ответ 3

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

Laravel \Request::ip() всегда возвращает 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: Он использует Laravel Request::ip(), так что все ваши посетители будут идентифицированы как тот же пользователь, и вы будете очень быстро ударил предел дросселя, Опыт в жизни... это привело меня к большим проблемам...

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

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

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

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

Ответ 4

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

use Request;

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

Request::ip();

Ответ 5

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

$request->ip();

Ответ 6

В Laravel 5

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

Ответ 7

Если вы все еще получаете 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

Ответ 8

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

 use Illuminate\Http\Request;

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

Ответ 9

Если вы хотите, чтобы клиентский IP-адрес и ваш сервер находились за aws-elb, тогда введите следующий код. Протестировано для laravel 5.3

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

Ответ 10

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

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

request()->ip();

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

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

Зачем?

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

Как?

Если вы не используете AWS balance-loader

Перейдите в App\Http\Middleware\TrustProxies

и сделать объявление $proxies похожим на это:

protected $proxies = '*';

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

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

Проверено в Laravel 5.7

Ответ 11

Если вы вызываете эту функцию, вы легко получаете 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;
    }

Ответ 12

В новой версии вы можете получить его с запросом помощника

request()->ip();

Ответ 13

Когда нам нужен пользователь ip_address:

$_SERVER['REMOTE_ADDR']

и хотите адрес сервера:

$_SERVER['SERVER_ADDR']