How to get client IP address in Laravel 5+?

╄→гoц情女王★ 提交于 2019-11-27 05:10:10

问题


I am trying to get the client's IP address in Laravel. As we all know that it is pretty much easier to get a client's IP in PHP by using $_SERVER["REMOTE_ADDR"].

It is working fine in core PHP, but when I use the same thing in Laravel, then it gives server IP instead of visitor IP.


回答1:


Looking at the Laravel API:

Request::ip();

Internally, it uses the getClientIps method from the 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);
} 



回答2:


Use request()->ip()

Since Laravel 5 it's (from what I understand) advised / good practice to use the global functions like:

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

You get the point :-) And if anything, when using the functions (instead of the static notarion) my IDE doesn't ligt up like a christmas tree ;-)




回答3:


If you are under a load balancer

Laravel's \Request::ip() always return the balancer's 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

This custom method returns the real client 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;
                }
            }
        }
    }
}

More: If you use the Laravel's throttle middleware

In addition to this I suggest you to be very careful using the Laravel's throttle middleware: It uses the Laravel's Request::ip() as well, so all your visitors will be identified as the same user and you will hit the throttle limit very quickly. Experienced in live...this led me to big issues...

To fix this:

Illuminate\Http\Request.php

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

You can now also use Request::ip(), which should return the real IP in production




回答4:


Add namespace

use Request;

Then call the function

Request::ip();



回答5:


For Laravel 5 you can use the Request object. Just call its ip() method. Something like:

$request->ip();




回答6:


In Laravel 5

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



回答7:


There are 2 things to take care of

1) get helper function that returns a Illuminate\Http\Request and call ->ip() method.

request()->ip();

2) Think of your server configuration, it may use proxy or load balancer (especially in AWS ELB config)

If this is your case you need to Configuring Trusted Proxies or maybe even set a Trusting All Proxiesoption.

Why?

Because being your server will be getting your proxy/balance-loader IP instead.

How?

If you are no AWS balance-loader

Go to App\Http\Middleware\TrustProxies

and make $proxies declaration look like this:

protected $proxies = '*';

Now test it and celebrate, because you just saved yourself from having trouble with throttle middleware. It also relies on request()->ip() and without setting TrustProxies up, you could have all your users blocked from logging in instead of blocking only the culprit's IP.

And because throttle middleware is not explained properly in documentation, I recommend watch this video

Tested in Laravel 5.7




回答8:


If you are still getting 127.0.0.1 as IP, you need to add your "proxy".

But beware that you have to change it before going production!!

Read this part: https://laravel.com/docs/5.7/requests#configuring-trusted-proxies

And now just add this:

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

Now request()->ip() gives you the correct ip




回答9:


in version laravel 5.4 we can't call ip static this a correct way to get ip user

 use Illuminate\Http\Request;

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



回答10:


If you want client IP and your server is behind aws elb, then user the following code. Tested for laravel 5.3

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



回答11:


If you call this function then you easily get the client IP address. I have already used this useful code in my existing project.

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:


When we want the user's ip_address:

$_SERVER['REMOTE_ADDR']

and want to server address:

$_SERVER['SERVER_ADDR']


来源:https://stackoverflow.com/questions/33268683/how-to-get-client-ip-address-in-laravel-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!