programing

PHP에서 클라이언트 IP 주소를 가져오는 방법

copysource 2022. 9. 18. 17:36
반응형

PHP에서 클라이언트 IP 주소를 가져오는 방법

PHP를 사용하여 클라이언트 IP 주소를 얻으려면 어떻게 해야 합니까?

제 웹사이트에 로그인한 사용자의 IP 주소를 기록하고 싶습니다.

어떤 방법으로든 클라이언트에서 전송된 데이터를 신뢰하지 마십시오. $_SERVER['REMOTE_ADDR'].그것이 당신이 찾을 수 있는 가장 신뢰할 수 있는 값입니다.

수 이, 에서는 「 」, 「 」가 되어 있을 가능성이 .이 경우 프록시는 이 서버를$_SERVER['HTTP_X_FORWARDED_FOR'], 이 예를 들어 프록시가 없는 사용자가 설정할 수도 있고 IP가 프록시 배후에 있는 LAN의 내부 IP일 수도 있습니다.

은, 「」를 는, 「」를 보존하는 것을 합니다.$_SERVER['HTTP_X_FORWARDED_FOR']반드시 저장해 주세요.$_SERVER['REMOTE_ADDR']예를 들어, 두 값을 모두 데이터베이스의 다른 필드에 저장함으로써 얻을 수 있습니다.

IP 를 문자열로서 데이터베이스에 보존하는 경우는, 45 문자 이상의 스페이스가 있는 것을 확인해 주세요.IPv6 는 계속 사용할 수 있습니다.이러한 주소는, 낡은 IPv4 주소보다 큽니다.

(통상, IPv6 에는 최대 39 문자의 IPv6 표기가 있습니다만, IPv4 주소에는, 최대 45 문자까지 사용할 수 있는 특수한 IPv6 표기도 합니다.따라서 자신이 무엇을 하고 있는지 알고 있다면 39자를 사용할 수 있지만 설정만 하고 잊어버리려면 45자를 사용하십시오.

$_SERVER['REMOTE_ADDR']에는 실제 클라이언트 IP 주소가 포함되어 있지 않을 수 있습니다.이는 예를 들어 프록시를 통해 연결된 클라이언트의 프록시 주소를 제공하기 때문입니다.다만, IP로 무엇을 하고 있는지에 따라서는, 이것이 정말로 필요한 것일 가능성이 있습니다.트래픽의 발신원을 확인하려고 하거나 사용자가 마지막으로 접속한 IP를 기억하려고 하거나 프록시 또는 NAT 게이트웨이의 퍼블릭 IP를 저장하는 것이 적절한 경우, 다른 사용자의 개인 RFC 1918 주소가 도움이 되지 않을 수 있습니다.

헤더에는 "HTTP"와 같은 여러 가 있습니다.X-Forwarded-For다양한 프록시에 의해 설정되거나 설정되지 않을 수 있습니다.문제는 이것들은 누구나 설정할 수 있는HTTP 헤더에 불과하다는 것입니다.을 사용법 $_SERVER['REMOTE_ADDR']는, 해, 입니다.Web " " " " " " " " " 、 " " IP " " " 。그 외의 것은 임의적이고 자발적인 정보일 뿐이다.이 정보를 신뢰할 수 있는 시나리오는 이 헤더를 설정하는 프록시를 제어하는 경우뿐입니다.이는 헤더가 설정된 위치와 방법을 100% 알고 있는 경우에만 중요한 사항에 주의를 기울여야 한다는 의미입니다.

그럼, 샘플 코드는 다음과 같습니다.

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

편집자 메모:위의 코드를 사용하면 보안에 영향이 있습니다.클라이언트는 모든 HTTP 헤더 정보를 설정할 수 있습니다(즉, $_SERVER['HTTP_...원하는 임의의 값을 지정합니다. 때문에 그, 용, 용, 용, 용, 사, 사, 사, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as as,$_SERVER['REMOTE_ADDR']사용자가 설정할 수 없습니다.

송신원: http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html

echo $_SERVER['REMOTE_ADDR'];

http://php.net/manual/en/reserved.variables.server.php

다음으로 사용자의 IP 주소를 취득하는 가장 좋은 방법의 클리너 코드샘플을 나타냅니다.

$ip = $_SERVER['HTTP_CLIENT_IP'] 
   ? $_SERVER['HTTP_CLIENT_IP'] 
   : ($_SERVER['HTTP_X_FORWARDED_FOR'] 
        ? $_SERVER['HTTP_X_FORWARDED_FOR'] 
        : $_SERVER['REMOTE_ADDR']);

다음은 elvis 오퍼레이터를 사용하는 단축 버전입니다.

$_SERVER['HTTP_CLIENT_IP'] 
   ? : ($_SERVER['HTTP_X_FORWARDED_FOR'] 
   ? : $_SERVER['REMOTE_ADDR']);

다음은 isset을 사용하여 알림을 삭제하는 버전입니다(@shasi kanth).

$ip = isset($_SERVER['HTTP_CLIENT_IP']) 
    ? $_SERVER['HTTP_CLIENT_IP'] 
    : (isset($_SERVER['HTTP_X_FORWARDED_FOR']) 
      ? $_SERVER['HTTP_X_FORWARDED_FOR'] 
      : $_SERVER['REMOTE_ADDR']);

은 '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.$_SERVER['REMOTE_ADDR']★★★★★★ 。

Zend Framework 2입니다., 「」도 되고 있습니다.$_SERVER 「」을 참조해 주세요.HTTP_X_FORWARDED_FOR,HTTP_CLIENT_IP,REMOTE_ADDR그러나 신뢰할 수 있는 프록시를 설정하기 위해 클래스를 선언하고 배열이 아닌 하나의 IP 주소를 반환합니다.저는 이것이 가장 가까운 해결책이라고 생각합니다.

class RemoteAddress
{
    /**
     * Whether to use proxy addresses or not.
     *
     * As default this setting is disabled - IP address is mostly needed to increase
     * security. HTTP_* are not reliable since can easily be spoofed. It can be enabled
     * just for more flexibility, but if user uses proxy to connect to trusted services
     * it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].
     *
     * @var bool
     */
    protected $useProxy = false;

    /**
     * List of trusted proxy IP addresses
     *
     * @var array
     */
    protected $trustedProxies = array();

    /**
     * HTTP header to introspect for proxies
     *
     * @var string
     */
    protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';

    // [...]

    /**
     * Returns client IP address.
     *
     * @return string IP address.
     */
    public function getIpAddress()
    {
        $ip = $this->getIpAddressFromProxy();
        if ($ip) {
            return $ip;
        }

        // direct IP address
        if (isset($_SERVER['REMOTE_ADDR'])) {
            return $_SERVER['REMOTE_ADDR'];
        }

        return '';
    }

    /**
     * Attempt to get the IP address for a proxied client
     *
     * @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
     * @return false|string
     */
    protected function getIpAddressFromProxy()
    {
        if (!$this->useProxy
            || (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], $this->trustedProxies))
        ) {
            return false;
        }

        $header = $this->proxyHeader;
        if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) {
            return false;
        }

        // Extract IPs
        $ips = explode(',', $_SERVER[$header]);
        // trim, so we can compare against trusted proxies properly
        $ips = array_map('trim', $ips);
        // remove trusted proxy IPs
        $ips = array_diff($ips, $this->trustedProxies);

        // Any left?
        if (empty($ips)) {
            return false;
        }

        // Since we've removed any known, trusted proxy servers, the right-most
        // address represents the first IP we do not know about -- i.e., we do
        // not know if it is a proxy server, or a client. As such, we treat it
        // as the originating IP.
        // @see http://en.wikipedia.org/wiki/X-Forwarded-For
        $ip = array_pop($ips);
        return $ip;
    }

    // [...]
}

자세한 코드는, https://raw.githubusercontent.com/zendframework/zend-http/master/src/PhpEnvironment/RemoteAddress.php 를 참조해 주세요.

인터넷 뒤에는 다양한 유형의 사용자가 있기 때문에 다른 부분에서 IP 주소를 취득하고 싶습니다.다음과 같은 것이 있습니다.

1. 클라이언트의 실제 IP 주소가 포함됩니다.이 값은 사용자에게서 찾을 수 있는 가장 신뢰할 수 있는 값입니다.

2. - 사용자가 현재 페이지를 보고 있는 호스트 이름을 가져옵니다.단, 이 스크립트가 기능하려면 httpd.conf 내의 호스트명 룩업을 설정해야 합니다.

3. - 사용자가 공유 인터넷 서비스에서 온 경우 IP 주소를 가져옵니다.

4. - 사용자가 프록시 뒤에 있을 때 IP 주소를 가져옵니다.

따라서 이 복합 함수를 사용하여 다른 위치에 있는 사용자로부터 실제 IP 주소를 얻을 수 있습니다.

// Function to get the user IP address
function getUserIP() {
    $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_X_CLUSTER_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    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;
}

다음은 제가 지금까지 발견한 방법 중 가장 진보된 방법이며, 이전에 몇 가지 시도해 본 적이 있습니다.방문자의 IP 주소를 확실히 취득하는 것은 유효합니다(단, 해커라면 IP 주소를 조작하기 쉬운 경우가 있습니다).

function get_ip_address() {

    // Check for shared Internet/ISP IP
    if (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    }

    // Check for IP addresses passing through proxies
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {

        // Check if multiple IP addresses exist in var
        if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false) {
            $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            foreach ($iplist as $ip) {
                if (validate_ip($ip))
                    return $ip;
            }
        }
        else {
            if (validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']))
                return $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
    }
    if (!empty($_SERVER['HTTP_X_FORWARDED']) && validate_ip($_SERVER['HTTP_X_FORWARDED']))
        return $_SERVER['HTTP_X_FORWARDED'];
    if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
        return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && validate_ip($_SERVER['HTTP_FORWARDED_FOR']))
        return $_SERVER['HTTP_FORWARDED_FOR'];
    if (!empty($_SERVER['HTTP_FORWARDED']) && validate_ip($_SERVER['HTTP_FORWARDED']))
        return $_SERVER['HTTP_FORWARDED'];

    // Return unreliable IP address since all else failed
    return $_SERVER['REMOTE_ADDR'];
}

/**
 * Ensures an IP address is both a valid IP address and does not fall within
 * a private network range.
 */
function validate_ip($ip) {

    if (strtolower($ip) === 'unknown')
        return false;

    // Generate IPv4 network address
    $ip = ip2long($ip);

    // If the IP address is set and not equivalent to 255.255.255.255
    if ($ip !== false && $ip !== -1) {
        // Make sure to get unsigned long representation of IP address
        // due to discrepancies between 32 and 64 bit OSes and
        // signed numbers (ints default to signed in PHP)
        $ip = sprintf('%u', $ip);

        // Do private network range checking
        if ($ip >= 0 && $ip <= 50331647)
            return false;
        if ($ip >= 167772160 && $ip <= 184549375)
            return false;
        if ($ip >= 2130706432 && $ip <= 2147483647)
            return false;
        if ($ip >= 2851995648 && $ip <= 2852061183)
            return false;
        if ($ip >= 2886729728 && $ip <= 2887778303)
            return false;
        if ($ip >= 3221225984 && $ip <= 3221226239)
            return false;
        if ($ip >= 3232235520 && $ip <= 3232301055)
            return false;
        if ($ip >= 4294967040)
            return false;
    }
    return true;
}

정답은 변수를 사용하는 것입니다.예를들면,$_SERVER["REMOTE_ADDR"]IP를 사용합니다.

신속한 해결(오류 없음)

function getClientIP():string
{
    $keys=array('HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_FORWARDED_FOR','HTTP_FORWARDED','REMOTE_ADDR');
    foreach($keys as $k)
    {
        if (!empty($_SERVER[$k]) && filter_var($_SERVER[$k], FILTER_VALIDATE_IP))
        {
            return $_SERVER[$k];
        }
    }
    return "UNKNOWN";
}
function get_client_ip()
{
    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)) {
            foreach (explode(',', $_SERVER[$key]) as $ip) {
                $ip = trim($ip);
                if ((bool) filter_var($ip, FILTER_VALIDATE_IP,
                                FILTER_FLAG_IPV4 |
                                FILTER_FLAG_NO_PRIV_RANGE |
                                FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
    }
    return null;
}

또는 압축된 버전:

function get_ip() {
    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 (array_map('trim', explode(',', $_SERVER[$key])) as $ip) {
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
                    return $ip;
                }
            }
        }
    }
}

여기에서는 다양한 소스를 통해 확인함으로써 유효한 IP를 선택해야 하는 코드를 보여 줍니다.

우선, 「REMOTE_ADDR」이 퍼블릭 IP인지 아닌지를 체크하고(신뢰할 수 있는 리버스 프록시 중 하나가 아님), 퍼블릭 IP를 찾아 반환할 때까지 HTTP 헤더 중 하나를 통과합니다(PHP 5.2+).

역방향 프록시를 신뢰하거나 서버가 클라이언트에 직접 연결되어 있는 한 신뢰성이 높아야 합니다.

//Get client's IP or null if nothing looks valid
function ip_get($allow_private = false)
{
  //Place your trusted proxy server IPs here.
  $proxy_ip = ['127.0.0.1'];

  //The header to look for (Make sure to pick the one that your trusted reverse proxy is sending or else you can get spoofed)
  $header = 'HTTP_X_FORWARDED_FOR'; //HTTP_CLIENT_IP, HTTP_X_FORWARDED, HTTP_FORWARDED_FOR, HTTP_FORWARDED

  //If 'REMOTE_ADDR' seems to be a valid client IP, use it.
  if(ip_check($_SERVER['REMOTE_ADDR'], $allow_private, $proxy_ip)) return $_SERVER['REMOTE_ADDR'];

  if(isset($_SERVER[$header]))
  {
    //Split comma separated values [1] in the header and traverse the proxy chain backwards.
    //[1] https://en.wikipedia.org/wiki/X-Forwarded-For#Format
    $chain = array_reverse(preg_split('/\s*,\s*/', $_SERVER[$header]));
    foreach($chain as $ip) if(ip_check($ip, $allow_private, $proxy_ip)) return $ip;
  }

   return null;
}

//Check for valid IP. If 'allow_private' flag is set to truthy, it allows private IP ranges as valid client IP as well. (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
//Pass your trusted reverse proxy IPs as $proxy_ip to exclude them from being valid.
function ip_check($ip, $allow_private = false, $proxy_ip = [])
{
  if(!is_string($ip) || is_array($proxy_ip) && in_array($ip, $proxy_ip)) return false;
  $filter_flag = FILTER_FLAG_NO_RES_RANGE;

  if(!$allow_private)
  {
    //Disallow loopback IP range which doesn't get filtered via 'FILTER_FLAG_NO_PRIV_RANGE' [1]
    //[1] https://www.php.net/manual/en/filter.filters.validate.php
    if(preg_match('/^127\.$/', $ip)) return false;
    $filter_flag |= FILTER_FLAG_NO_PRIV_RANGE;
  }

  return filter_var($ip, FILTER_VALIDATE_IP, $filter_flag) !== false;
}

처럼, 전에 할 수 .$_SERVER['REMOTE_ADDR'];IP를 사용합니다.

또한 사용자에 대한 자세한 정보가 필요한 경우 다음을 사용할 수 있습니다.

<?php
    $ip = '0.0.0.0';
    $ip = $_SERVER['REMOTE_ADDR'];
    $clientDetails = json_decode(file_get_contents("http://ipinfo.io/$ip/json"));
    echo "You're logged in from: <b>" . $clientDetails->country . "</b>";
?>

$client Details clientclient 。
$clientDetails JSON Details 。$client Details -> 우편번호 / 호스트명 / 지역 / loc ...

저는 ipinfo.io을 사용하여 추가 정보를 얻고 있습니다.

코드니펫이 마음에 들어요

function getClientIP() {

    if (isset($_SERVER)) {

        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
            return $_SERVER["HTTP_X_FORWARDED_FOR"];

        if (isset($_SERVER["HTTP_CLIENT_IP"]))
            return $_SERVER["HTTP_CLIENT_IP"];

        return $_SERVER["REMOTE_ADDR"];
    }

    if (getenv('HTTP_X_FORWARDED_FOR'))
        return getenv('HTTP_X_FORWARDED_FOR');

    if (getenv('HTTP_CLIENT_IP'))
        return getenv('HTTP_CLIENT_IP');

    return getenv('REMOTE_ADDR');
}
$ip = "";

if (!empty($_SERVER["HTTP_CLIENT_IP"]))
{
    // Check for IP address from shared Internet
    $ip = $_SERVER["HTTP_CLIENT_IP"];
}
elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
{
    // Check for the proxy user
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else
{
    $ip = $_SERVER["REMOTE_ADDR"];
}
echo $ip;

사용하고 있는 방법은, IPv4 입력의 유효성을 확인하는 것입니다.

// Get user IP address
if ( isset($_SERVER['HTTP_CLIENT_IP']) && ! empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && ! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
}

$ip = filter_var($ip, FILTER_VALIDATE_IP);
$ip = ($ip === false) ? '0.0.0.0' : $ip;

이렇게 할 수 요.GLOBAL「」라고 하는 $_SERVER.

$_SERVER는, 이 「아트리뷰트명」을입니다.REMOTE_ADDR.

다음과 같이 할당합니다.

$userIp = $_SERVER['REMOTE_ADDR'];

' 낫다'처럼 바로 하세요.echo $_SERVER['REMOTE_ADDR']; ★★★★★★★★★★★★★★★★★」echo ($_SERVER['REMOTE_ADDR']);.

다음 중 하나:

    $ip = $_SERVER['REMOTE_ADDR'];
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    $ip = $_SERVER['HTTP_X_FORWARDED'];
    $ip = $_SERVER['HTTP_FORWARDED_FOR'];
    $ip = $_SERVER['HTTP_FORWARDED'];

이 기능은 콤팩트하고 어디서나 사용할 수 있습니다.하지만!

잊지 마세요!이러한 유형의 함수 또는 코드 블록에서는 사용자의 실제 IP 주소를 기록할 수 없습니다.이는 일부 사용자가 프록시 또는 다른 보안 게이트웨이를 사용하여 보이지 않거나 추적할 수 없기 때문입니다.

PHP 함수:

function GetIP()
{
    if ( getenv("HTTP_CLIENT_IP") ) {
        $ip = getenv("HTTP_CLIENT_IP");
    } elseif ( getenv("HTTP_X_FORWARDED_FOR") ) {
        $ip = getenv("HTTP_X_FORWARDED_FOR");
        if ( strstr($ip, ',') ) {
            $tmp = explode(',', $ip);
            $ip = trim($tmp[0]);
        }
    } else {
        $ip = getenv("REMOTE_ADDR");
    }
    return $ip;
}

사용방법:

$IP = GetIP(); 직접(직접)GetIP();

IP 주소를 취득하기 위한 안전하고 경고 대응 스니펫:

$ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_VALIDATE_IP)
    ?: filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_VALIDATE_IP)
    ?: $_SERVER['REMOTE_ADDR']
    ?? '0.0.0.0'; // Or other value fits "not defined" in your logic

다음 함수는 모든 가능성을 확인하고 값을 쉼표로 구분된 형식(ip, ip 등)으로 반환합니다.

또, 옵션의 검증 기능(디폴트로 디세블로 되어 있는 최초의 파라메타)이 있어, (프라이빗 범위와 예약 범위)에 대해서 IP 주소를 검증합니다.

<?php
echo GetClientIP(true);

function GetClientIP($validate = False) {
  $ipkeys = array(
  'REMOTE_ADDR',
  'HTTP_CLIENT_IP',
  'HTTP_X_FORWARDED_FOR',
  'HTTP_X_FORWARDED',
  'HTTP_FORWARDED_FOR',
  'HTTP_FORWARDED',
  'HTTP_X_CLUSTER_CLIENT_IP'
  );

  /*
  Now we check each key against $_SERVER if containing such value
  */
  $ip = array();
  foreach ($ipkeys as $keyword) {
    if (isset($_SERVER[$keyword])) {
      if ($validate) {
        if (ValidatePublicIP($_SERVER[$keyword])) {
          $ip[] = $_SERVER[$keyword];
        }
      }
      else{
        $ip[] = $_SERVER[$keyword];
      }
    }
  }

  $ip = ( empty($ip) ? 'Unknown' : implode(", ", $ip) );
  return $ip;
}

function ValidatePublicIP($ip){
  if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
    return true;
  }
  else {
    return false;
  }
}

이것을 사용해 보세요.

 $_SERVER['REMOTE_ADDR'];

<?php
/**
 * Function to get the client ip address
 *
 * @return string The Ip address
 */
function getIp(): string {
    if (! empty($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    }

    if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        return $_SERVER['HTTP_X_FORWARDED_FOR'];
    }

    return $_SERVER['REMOTE_ADDR'] ?? '?';
}

더 작다

/**
 * Function to get the client ip address
 *
 * @return string The Ip address
 */
function getIp(): string {
    return $_SERVER['HTTP_CLIENT_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
}

아직 언급되지 않은 것은 놀랍지만 CloudFlare 인프라스트럭처 등의 배후에 있는 사이트의 올바른 IP 주소를 얻는 것입니다.그러면 IP 주소가 끊어지고 모든 IP 주소가 동일한 값이 지정됩니다.다행히 서버 헤더도 몇 개 있습니다.제가 이미 쓴 것을 다시 쓰는 대신, 여기를 찾아봐서 좀 더 간결하게 대답해 주세요. 네, 저도 오래 전에 이 과정을 거쳤습니다.https://stackoverflow.com/a/14985633/1190051

여기 간단한 라이너가 하나 있습니다.

$ip = $_SERVER['HTTP_X_FORWARDED_FOR']?: $_SERVER['HTTP_CLIENT_IP']?: $_SERVER['REMOTE_ADDR'];

편집:

위의 코드는 예약된 주소(10.0.0.1 등), 전송 중인 모든 프록시 서버의 주소 목록 등을 반환할 수 있습니다.이러한 경우에 대처하려면 , 다음의 코드를 사용합니다.

function valid_ip($ip) {
    // for list of reserved IP addresses, see https://en.wikipedia.org/wiki/Reserved_IP_addresses
    return $ip && substr($ip, 0, 4) != '127.' && substr($ip, 0, 4) != '127.' && substr($ip, 0, 3) != '10.' && substr($ip, 0, 2) != '0.' ? $ip : false;
}

function get_client_ip() {
    // using explode to get only client ip from list of forwarders. see https://en.wikipedia.org/wiki/X-Forwarded-For
    return
    @$_SERVER['HTTP_X_FORWARDED_FOR'] ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2)[0] :
    @$_SERVER['HTTP_CLIENT_IP'] ? explode(',', $_SERVER['HTTP_CLIENT_IP'], 2)[0] :
    valid_ip(@$_SERVER['REMOTE_ADDR']) ?:
    'UNKNOWN';
}

echo get_client_ip();

이 기능은 예상대로 작동합니다.

function Get_User_Ip()
{
    $IP = false;
    if (getenv('HTTP_CLIENT_IP'))
    {
        $IP = getenv('HTTP_CLIENT_IP');
    }
    else if(getenv('HTTP_X_FORWARDED_FOR'))
    {
        $IP = getenv('HTTP_X_FORWARDED_FOR');
    }
    else if(getenv('HTTP_X_FORWARDED'))
    {
        $IP = getenv('HTTP_X_FORWARDED');
    }
    else if(getenv('HTTP_FORWARDED_FOR'))
    {
        $IP = getenv('HTTP_FORWARDED_FOR');
    }
    else if(getenv('HTTP_FORWARDED'))
    {
        $IP = getenv('HTTP_FORWARDED');
    }
    else if(getenv('REMOTE_ADDR'))
    {
        $IP = getenv('REMOTE_ADDR');
    }

    //If HTTP_X_FORWARDED_FOR == server ip
    if((($IP) && ($IP == getenv('SERVER_ADDR')) && (getenv('REMOTE_ADDR')) || (!filter_var($IP, FILTER_VALIDATE_IP))))
    {
        $IP = getenv('REMOTE_ADDR');
    }

    if($IP)
    {
        if(!filter_var($IP, FILTER_VALIDATE_IP))
        {
            $IP = false;
        }
    }
    else
    {
        $IP = false;
    }
    return $IP;
}

PHP의 IP여야 합니다.$_SERVER["REMOTE_ADDR"]너무 많은 보안상의 이유로요

클라이언트의 검증된 IP 주소를 취득하기 위한 회피책은 다음과 같습니다.

public static function getPublicIP() : string
    {
        $realIP = "Invalid IP Address";

        $activeHeaders = [];

        $headers = [
            "HTTP_CLIENT_IP",
            "HTTP_PRAGMA",
            "HTTP_XONNECTION",
            "HTTP_CACHE_INFO",
            "HTTP_XPROXY",
            "HTTP_PROXY",
            "HTTP_PROXY_CONNECTION",
            "HTTP_VIA",
            "HTTP_X_COMING_FROM",
            "HTTP_COMING_FROM",
            "HTTP_X_FORWARDED_FOR",
            "HTTP_X_FORWARDED",
            "HTTP_X_CLUSTER_CLIENT_IP",
            "HTTP_FORWARDED_FOR",
            "HTTP_FORWARDED",
            "ZHTTP_CACHE_CONTROL",
            "REMOTE_ADDR" #this should be the last option
        ];

        #Find active headers
        foreach ($headers as $key)
        {
            if (array_key_exists($key, $_SERVER))
            {
                $activeHeaders[$key] = $_SERVER[$key];
            }
        }

         #Reemove remote address since we got more options to choose from
        if(count($activeHeaders) > 1)
        {
            unset($activeHeaders["REMOTE_ADDR"]);
        }

        #Pick a random item now that we have a secure way.
        $realIP = $activeHeaders[array_rand($activeHeaders)];

        #Validate the public IP
        if (filter_var($realIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
        {
            return $realIP;
        }

        return $realIP;
    }

보시다시피 $_SERVER["REMOTE_ADDR"]는 IP에 대한 마지막 옵션입니다.IP를 받은 후 품질과 보안을 보장하기 위해 IP도 검증합니다.

if-else/switch 문을 사용하지 않는 경우 다음 솔루션이 적합합니다.

function get_client_ip()
{
    $fields = array(
        'HTTP_CF_CONNECTING_IP',
        'HTTP_X_SUCURI_CLIENTIP',
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR',
        // more custom fields
    );

    foreach ($fields as $ip_field) {
        if (!empty($_SERVER[$ip_field])) {
            return $_SERVER[$ip_field];
        }
    }

    return null;
}

아래 기능을 사용할 수 있습니다.

function get_client_ip() {
    $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;
}

다음과 같이요?

if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', validate_ip)) === false or empty($ip)) {
    exit;
}
echo $ip;

PS

if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP|FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)) === false) {
    header('HTTP/1.0 400 Bad Request');
    exit;
}

각각 'HTTP_' 또는 'X-'로 시작하는 모든 헤더는 스푸핑할 수 있습니다.추적하려면 쿠키 등을 사용하십시오.

언급URL : https://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php

반응형