php 如何在 Laravel 5+ 中获取客户端 IP 地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33268683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:25:54  来源:igfitidea点击:

How to get client IP address in Laravel 5+

phplaravellaravel-5laravel-5.7

提问by Amrinder Singh

I am trying to get the client's IP address in Laravel.

我正在尝试在 Laravel 中获取客户端的 IP 地址。

It is easy 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, it returns the server IP instead of the visitor's IP.

使用 .php 可以很容易地在 PHP 中获取客户端的 IP $_SERVER["REMOTE_ADDR"]。它在核心 PHP 中运行良好,但是当我在 Laravel 中使用相同的东西时,它返回服务器 IP 而不是访问者的 IP。

回答by samlev

Looking at the Laravel API:

查看Laravel API

Request::ip();

Internally, it uses the getClientIpsmethod from the Symfony Request Object:

在内部,它使用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);
} 

回答by Sebastien Horin

If you are under a load balancer, Laravel's \Request::ip()alwaysreturns the balancer's IP:

如果你在负载均衡器下,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

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

In addition to this I suggest you to be very careful using Laravel's throttlemiddleware: It uses 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. I experienced this live and this caused big issues.

除此之外,我建议您在使用 Laravel 的油门中间件时要非常小心:它也使用 Laravel 的中间件Request::ip(),因此您的所有访问者都将被识别为同一用户,并且您将很快达到油门限制。我现场体验了这件事,这引起了大问题。

To fix this:

要解决此问题:

Illuminate\Http\Request.php

照亮\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.

您现在还可以使用Request::ip(),它应该返回生产中的真实 IP。

回答by Stan Smulders

Use request()->ip().

使用request()->ip().

From what I understand, since Laravel 5 it's advised/good practice to use the global functions like:

据我了解,从 Laravel 5 开始,建议/好的做法是使用全局函数,例如:

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

And, if anything, when using the functions instead of the static notation my IDE doesn't light up like a Christmas tree.

而且,如果有的话,当使用函数而不是静态符号时,我的 IDE 不会像圣诞树一样亮起来。

回答by shalini

Add namespace

添加命名空间

use Request;

Then call the function

然后调用函数

Request::ip();

回答by Todor Todorov

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

对于 Laravel 5,您可以使用 Request 对象。只需调用它的ip()方法,例如:

$request->ip();

回答by Govind Samrow

In Laravel 5

在 Laravel 5

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

回答by Yevgeniy Afanasyev

There are two things to take care of:

有两件事需要注意:

  1. Get a helper function that returns a Illuminate\Http\Requestand call the ->ip()method:

    request()->ip();
    
  2. Think of your server configuration, it may use a proxy or load-balancer, especially in an AWS ELB configuration.

  1. 获取一个返回 a 的辅助函数Illuminate\Http\Request并调用该->ip()方法:

    request()->ip();
    
  2. 想想您的服务器配置,它可能使用代理或load-balancer,尤其是在 AWS ELB 配置中。

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

如果是这种情况,您需要遵循“配置受信任的代理”或者甚至设置“信任所有代理”选项。

Why? Because being your server will be getting your proxy/load-balancerIP instead.

为什么?因为成为您的服务器将获得您的代理/ load-balancerIP。

If you are on the AWS balance-loader, go to App\Http\Middleware\TrustProxiesand make $proxiesdeclaration look like this:

如果您在 AWS balance-loader 上,请转到App\Http\Middleware\TrustProxies并进行如下$proxies声明:

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.

现在测试它并庆祝一下,因为您刚刚避免了油门中间件的麻烦。它还依赖于request()->ip()和不设置“TrustProxies”,您可以阻止所有用户登录,而不是仅阻止罪魁祸首的 IP。

And because throttle middleware is not explained properly in the documentation, I recommend watching "laravel 5.2 tutorial for beginner, API Rate Limiting"

并且由于文档中没有正确解释油门中间件,我建议观看“ laravel 5.2 初学者教程,API 速率限制

Tested in Laravel 5.7

在 Laravel 5.7 中测试

回答by Soura Sankar Ghosh

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

如果你调用这个函数,那么你很容易得到客户端的 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;
    }

回答by Shadrix

If you are still getting 127.0.0.1 as the IP, you need to add your "proxy", but be aware that you have to change it before going into production!

如果您仍然获得 127.0.0.1 作为 IP,则需要添加您的“代理”,但请注意,您必须在投入生产之前对其进行更改!

Read "Configuring Trusted Proxies".

阅读“配置可信代理”。

And add this:

并添加这个:

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

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

现在request()->ip()给你正确的IP。

回答by Vahid Alvandi

In Laravel 5.4 we can't call ip static. This a correct way to get the IP of the user:

在 Laravel 5.4 中我们不能调用 ip static。这是获取用户IP的正确方法:

 use Illuminate\Http\Request;

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