PHP most accurate / safe way to get real user IP address in 2017

后端 未结 10 481
粉色の甜心
粉色の甜心 2021-01-01 15:51

What is the most accurate way to get user\'s IP address in 2017 via PHP?

I\'ve read a lot of SO questions and answers about it, but most of answers are old and comme

相关标签:
10条回答
  • 2021-01-01 16:24

    I use this code, and it works for me. Take a look to it.

    <?php
    
    // Gets client's IP.
    $ip = getenv("HTTP_CLIENT_IP")?:
    getenv("HTTP_X_FORWARDED_FOR")?:
    getenv("HTTP_X_FORWARDED")?:
    getenv("HTTP_FORWARDED_FOR")?:
    getenv("HTTP_FORWARDED")?:
    getenv("REMOTE_ADDR");
    
    echo $ip;
    
    ?>
    

    Here, a working example. Hope it helps!

    0 讨论(0)
  • 2021-01-01 16:29

    How about this one -

    public function getClientIP()
        {
            $remoteKeys = [
                'HTTP_X_FORWARDED_FOR',
                'HTTP_CLIENT_IP',
                'HTTP_X_FORWARDED',
                'HTTP_FORWARDED_FOR',
                'HTTP_FORWARDED',
                'REMOTE_ADDR',
                'HTTP_X_CLUSTER_CLIENT_IP',
            ];
    
            foreach ($remoteKeys as $key) {
                if ($address = getenv($key)) {
                    foreach (explode(',', $address) as $ip) {
                        if ($this->isValidIp($ip)) {
                            return $ip;
                        }
                    }
                }
            }
    
            return '127.0.0.0';
        }
    
    
        private function isValidIp($ip)
        {
            if (!filter_var($ip, FILTER_VALIDATE_IP,
                    FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
                && !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE)
            ) {
                return false;
            }
    
            return true;
        }
    
    0 讨论(0)
  • 2021-01-01 16:32

    From a security POV, nothing but $_SERVER['REMOTE_ADDR'] is reliable - that's just the simple truth, unfortunately.

    All the variables prefixed with HTTP_ are in fact HTTP headers sent by the client, and there there's no other way to transfer that information while requests pass through different servers.
    But that of course automatically means that clients can spoof those headers.

    You can never, ever trust the client.

    Unless it is you ... If you control the proxy or load-balancer, it is possible to configure it so that it drops such headers from the original request.
    Then, and only then, you could trust an e.g. X-Client-IP header, but really, there's no need to at that point ... your webserver can also be configured to replace REMOTE_ADDR with that value and the entire process becomes transparent to you.

    This will always be the case, no matter which year we are in ... for anything related to security - only trust REMOTE_ADDR.
    Best case scenario is to read the HTTP_ data for statistical purposes only, and even then - make sure that the input is at least a valid IP address.

    0 讨论(0)
  • 2021-01-01 16:38
    1. Because of different network setups (proxy servers, private networks, etc.) and how administrators configure their networks, it is difficult to obtain the client IP address. Standards are being addressed related to this issue.

    2. The following function worked in 4 different tests (Home Network, VPN, Remote connection, public internet). The code can be used as base code for your project. Modify as needed.

    3. The function does validate the IP address, but does not validate IP ranges. This would be an additional test after you obtain the client IP.

    4. $_SERVER["REMOTE_ADDR"] does not always return the true client IP address.

    5. Because some of the parameters can be set by end users, security can be an issue.

    Set Client IP address

    $clientIpAddress = $du->setClientIpAddress($_SERVER);

    public function setClientIpAddress($serverVars) {
        # Initialization
        $searchList = "HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR,HTTP_X_FORWARDED,HTTP_X_CLUSTER_CLIENT_IP,HTTP_FORWARDED_FOR,HTTP_FORWARDED,REMOTE_ADDR";
        $clientIpAddress = "";
    
        # Loop through parameters
        $mylist = explode(',', $searchList);
        foreach ($mylist as $myItem) {
            # Is our list set?
            if (isset($serverVars[trim($myItem)])) {
                # Loop through IP addresses
                $myIpList = explode(',', $serverVars[trim($myItem)]);
                foreach ($myIpList as $myIp) {
                    if (filter_var(trim($myIp), FILTER_VALIDATE_IP)) {
                        # Set client IP address
                        $clientIpAddress = trim($myIp);
    
                        # Exit loop
                        break;
                    }
                }
            }
    
            # Did we find any IP addresses?
            if (trim($clientIpAddress) != "") {
                # Exit loop
                break;
            }
        }
    
        # Default (if needed)
        if (trim($clientIpAddress) == "") {
            # IP address was not found, use "Unknown"
            $clientIpAddress = "Unknown";
        }
    
        # Exit
        return $clientIpAddress;
    }
    
    0 讨论(0)
提交回复
热议问题