web-dev-qa-db-fra.com

Comment obtenir l'adresse IP du client dans Laravel 5+?

J'essaie d'obtenir l'adresse IP du client à Laravel. Comme nous le savons tous, il est beaucoup plus facile d'obtenir l'adresse IP d'un client dans PHP en utilisant $_SERVER["REMOTE_ADDR"].

Cela fonctionne très bien dans le noyau PHP, mais quand j'utilise la même chose dans Laravel, cela donne l'IP du serveur au lieu de l'IP du visiteur.

91
Amrinder Singh

En regardant l'API Laravel :

Request::ip();

En interne, il utilise la méthode getClientIps de Symfony Request Object :

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

Utilisez request()->ip() 

Depuis Laravel 5, il est (d'après ce que j'ai compris) conseillé/bonne pratique d'utiliser les fonctions globales telles que: 

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

Vous obtenez le point :-) Et si quelque chose, en utilisant les fonctions (au lieu du notarion statique) mon IDE ne s'allume pas comme un arbre de Noël ;-)

51
Stan Smulders

Si vous êtes sous un équilibreur de charge

\Request::ip()toujours de Laravel retourne l'adresse IP de l'équilibreur

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

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

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

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

Cette méthode personnalisée renvoie l'adresse IP réelle du client:

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;
                }
            }
        }
    }
}

Plus: Si vous utilisez le middleware d'accélérateur de Laravel

En plus de cela, je vous suggère de faire très attention en utilisant le middleware accélérateur de Laravel: il utilise également la Request::ip() de Laravel, de sorte que tous vos visiteurs seront identifiés comme étant le même utilisateur et que vous atteindrez très rapidement la limite des accélérateurs rapidement. Expérimenté en live ... cela m'a conduit à de gros problèmes ...

Pour résoudre ce problème:

Illuminer\Http\Request.php

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

Vous pouvez maintenant aussi utiliser Request::ip(), qui devrait retourner la vraie IP en production

46
Sebastien Horin

Ajouter un espace de noms 

use Request;

Puis appelez la fonction 

Request::ip();
22
shalini

À Laravel 5

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

dans la version laravel 5.4, nous ne pouvons pas appeler ip statique ceci une façon correcte d'obtenir l'utilisateur ip 

 use Illuminate\Http\Request;

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

Si vous voulez une adresse IP client et que votre serveur est derrière aws elb, utilisez le code suivant. Testé pour laravel 5.3

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

Il y a 2 choses à prendre en charge

1) obtient une fonction d'assistance qui retourne un Illuminate\Http\Request et appelle la méthode ->ip().

request()->ip();

2) Pensez à la configuration de votre serveur, il peut utiliser proxy ou load balancer (en particulier dans AWS ELB config)

Si tel est votre cas, vous devez Configuration des proxy approuvés ou peut-être même définir une Trusting All Proxiesoption.

Pourquoi?

Parce qu'être votre serveur, vous obtiendrez à la place votre IP proxy/balance-loader.

Comment?

Si vous n'êtes pas AWS balance-loader

Aller au App\Http\Middleware\TrustProxies

et donnez la déclaration $proxies à ceci:

protected $proxies = '*';

Maintenant testez-le et soyez heureux, car vous venez de vous éviter d'avoir des problèmes avec throttle middleware. Il s'appuie également sur request()->ip() et sans configurer TrustProxies, tous vos utilisateurs pourraient ne pas pouvoir se connecter au lieu de ne bloquer que l'adresse IP du coupable.

Et comme throttle middleware n'est pas expliqué correctement dans la documentation, je vous recommande de regarder cette vidéo

Testé à Laravel 5.7

1
Yevgeniy Afanasyev

Si vous obtenez toujours 127.0.0.1 en tant qu'IP, vous devez ajouter votre "proxy". 

Mais attention, il faut le changer avant de commencer la production !!

Lisez cette partie: https://laravel.com/docs/5.7/requests#configuring-trusted-proxies

Et maintenant, ajoutez simplement ceci:

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

Maintenant request () -> ip () vous donne l'adresse IP correcte

1
Shadrix

Si vous appelez cette fonction, vous obtenez facilement l'adresse IP du client . J'ai déjà utilisé ce code utile dans mon projet existant.

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