PHP를 사용하여 클라이언트 IP 주소를 얻으려면 어떻게 해야 합니까?
자신의 IP 주소를 통해 내 웹사이트에 로그인한 사용자의 기록을 유지하고 싶습니다.
질문자 :Anup Prakash
PHP를 사용하여 클라이언트 IP 주소를 얻으려면 어떻게 해야 합니까?
자신의 IP 주소를 통해 내 웹사이트에 로그인한 사용자의 기록을 유지하고 싶습니다.
무엇을 하든지 클라이언트에서 보낸 데이터를 신뢰하지 않도록 하십시오. $_SERVER['REMOTE_ADDR']
에는 연결 당사자의 실제 IP 주소가 포함됩니다. 그것이 당신이 찾을 수 있는 가장 신뢰할 수 있는 가치입니다.
그러나 프록시 서버 뒤에 있을 수 있으며 이 경우 프록시가 $_SERVER['HTTP_X_FORWARDED_FOR']
설정했을 수 있지만 이 값은 쉽게 스푸핑됩니다. 예를 들어 프록시가 없는 사람이 설정하거나 IP가 프록시 뒤에 있는 LAN의 내부 IP일 수 있습니다.
즉, $_SERVER['HTTP_X_FORWARDED_FOR']
를 저장하려는 경우 $_SERVER['REMOTE_ADDR']
값도 저장해야 합니다. 예를 들어 데이터베이스의 다른 필드에 두 값을 모두 저장합니다.
IP를 데이터베이스에 문자열로 저장하려면 45자 이상의 공백이 있어야 합니다. IPv6 은 계속 존재하며 해당 주소는 이전 IPv4 주소보다 큽니다.
(IPv6은 일반적으로 최대 39자를 사용하지만 전체 형식에서 최대 45자가 될 수 있는 IPv4 주소에 대한 특별한 IPv6 표기법도 있습니다. 따라서 수행 중인 작업을 알고 있다면 39자를 사용할 수 있지만 그냥 설정하고 잊어 버리려면 45를 사용하십시오).
$_SERVER['REMOTE_ADDR']
는 예를 들어 프록시를 통해 연결된 클라이언트에 대한 프록시 주소를 제공하므로 실제 클라이언트 IP 주소를 실제로 포함하지 않을 수 있습니다. IP로 무엇을 하느냐에 따라 그것이 정말로 원하는 것일 수도 있습니다. 누군가의 개인 RFC1918 주소는 트래픽이 어디에서 시작되었는지 확인하려고 하거나 사용자가 마지막으로 연결한 IP를 기억하거나 프록시 또는 NAT 게이트웨이의 공용 IP가 더 많을 수 있는 위치를 기억하는 경우 아무 소용이 없습니다. 보관하기에 적합합니다.
다양한 프록시에 의해 설정되거나 설정되지 않을 수 있는 X-Forwarded-For
와 같은 여러 HTTP 헤더가 있습니다. 문제는 이것이 누구나 설정할 수 있는 HTTP 헤더에 불과하다는 것입니다. 그들의 내용에 대한 보장은 없습니다. $_SERVER['REMOTE_ADDR']
은 웹 서버가 연결을 수신하고 응답을 보낼 실제 물리적 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_...
)를 원하는 임의의 값으로 설정할 수 있습니다. 따라서 사용자가 설정할 수 없으므로 $_SERVER['REMOTE_ADDR']
을 사용하는 것이 훨씬 더 안정적입니다.
에서: http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html
echo $_SERVER['REMOTE_ADDR'];
다음은 사용자의 IP 주소를 얻는 좋은 방법에 대한 보다 깔끔한 코드 샘플입니다.
$ip = $_SERVER['HTTP_CLIENT_IP'] ? $_SERVER['HTTP_CLIENT_IP'] : ($_SERVER['HTTP_X_FORWARDED_FOR'] ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
다음은 엘비스 연산자를 사용하는 더 짧은 버전입니다.
$_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 -- ie, 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; } // [...] }
인터넷 뒤에는 다양한 유형의 사용자가 있으므로 다른 부분에서 IP 주소를 파악하려고 합니다. 사람들은:
1. $_SERVER['REMOTE_ADDR']
- 클라이언트의 실제 IP 주소를 포함합니다. 사용자로부터 찾을 수 있는 가장 신뢰할 수 있는 값입니다.
2. $_SERVER['REMOTE_HOST']
- 사용자가 현재 페이지를 보고 있는 호스트 이름을 가져옵니다. 그러나 이 스크립트가 작동하려면 httpd.conf 내부에서 호스트 이름 조회를 구성해야 합니다.
3. $_SERVER['HTTP_CLIENT_IP']
- 사용자가 공유 인터넷 서비스에 있을 때 IP 주소를 가져옵니다.
4. $_SERVER['HTTP_X_FORWARDED_FOR']
- 사용자가 프록시 뒤에 있을 때 사용자의 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
변수를 사용하는 것입니다. 예를 들어 $_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; }
나는 이 코드 스니펫을 좋아한다:
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'); }
$_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>"; ?>
클라이언트의 보다 구체적인 정보는 $clientDetails에 있습니다.
$clientDetails 변수에 저장된 JSON 항목을 다음과 같이 가져올 수 있습니다. $clientDetails->PostalCode/hostname/region/loc...
추가 정보를 얻기 위해 ipinfo.io 를 사용하고 있습니다.
이것은 내가 사용하는 방법이며 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;
$_SERVER
라는 GLOBAL
변수를 사용하여 간단히 수행할 수 있습니다.
$_SERVER
는 속성 이름이 REMOTE_ADDR
배열입니다.
다음과 같이 할당하면 됩니다.
$userIp = $_SERVER['REMOTE_ADDR'];
또는 echo $_SERVER['REMOTE_ADDR'];
또는 echo ($_SERVER['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;
다음 중 하나:
$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 등)으로 반환합니다.
또한 선택적 유효성 검사 기능이 (기본적으로 비활성화된 첫 번째 매개변수) (개인 범위 및 예약된 범위)에 대해 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'];
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
<?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'] ?? ''; }
이 기능은 예상대로 작동해야 합니다.
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; }
다음은 간단한 한 라이너입니다.
$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();
이것에 대해 아직 언급되지 않았다는 사실에 놀랐습니다. CloudFlare 인프라와 같은 뒤에 자리 잡은 사이트의 올바른 IP 주소를 얻는 것입니다. 그것은 당신의 IP 주소를 깨고 그들 모두에게 같은 값을 줄 것입니다. 다행히 일부 서버 헤더도 사용할 수 있습니다. 이미 작성된 것을 다시 작성하는 대신 여기에서 좀 더 간결한 답변을 찾아보세요. 네, 저도 오래전에 이 과정을 겪었습니다. https://stackoverflow.com/a/14985633/1190051
다음과 같이?
if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', validate_ip)) === false or empty($ip)) { exit; } echo $ip;
추신
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-'로 시작하는 모든 헤더는 각각 사용자 정의에 따라 스푸핑될 수 있습니다. 추적을 원하시면 쿠키 등을 사용하십시오.
클라이언트 IP 주소를 얻으려면 getenv("REMOTE_ADDR")
를 사용하십시오.
예를 들어,
$ip_address = getenv("REMOTE_ADDR"); echo $ip_address;
localhost를 사용하여 서버를 호출하면 ::1
이 출력됩니다. 따라서 직접 서버 IP 주소 또는 도메인을 사용하여 서버를 호출하십시오.
출처 : http:www.stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php
파일이 있는 폴더를 Unix/Linux의 다른 폴더로 복사하려면 어떻게 합니까? [닫은] (0) | 2023.04.23 |
---|---|
프로젝트를 Eclipse로 가져온 후 '수퍼클래스 메서드를 재정의해야 함' 오류 (0) | 2023.04.23 |
여러 PDF 파일을 하나의 PDF로 병합/변환 (0) | 2023.04.23 |
AngularJS를 사용하여 브라우저 콘솔에서 $scope 변수에 어떻게 액세스합니까? (0) | 2023.04.23 |
Node.js에서 npm 모듈을 어떻게 제거합니까? (0) | 2023.04.23 |