Comment obtenir L'adresse IP du client en PHP?
23 réponses
quoi que vous fassiez, assurez-vous de ne pas faire confiance aux données envoyées par le client. $_SERVER['REMOTE_ADDR']
contient l'adresse IP réelle de la partie de connexion. C'est la valeur la plus fiable que vous pouvez trouver.
Toutefois, ils peuvent être derrière un serveur proxy auquel cas le proxy peut définir le $_SERVER['HTTP_X_FORWARDED_FOR']
, mais cette valeur est facilement usurpée. Par exemple, il peut être défini par quelqu'un sans proxy, ou L'IP peut être une IP interne du LAN derrière le proxy.
cela signifie que si vous voulez enregistrer la $_SERVER['HTTP_X_FORWARDED_FOR']
, assurez-vous que vous aussi save the $_SERVER['REMOTE_ADDR']
valeur. Par exemple: en sauvegardant les deux valeurs dans différents champs de votre base de données.
si vous voulez sauvegarder L'IP dans une base de données en tant que chaîne de caractères, assurez-vous que vous avez de l'espace pour au moins 45 caractères . IPv6 est ici pour rester et ces adresses sont plus grandes que les anciennes adresses IPv4.
(notez que IPv6 utilise habituellement 39 caractères au maximum, mais il y a aussi une notation spéciale IPv6 pour les adresses IPv4 qui dans sa forme complète peut être jusqu'à 45 caractères. Donc, si vous savez ce que vous faites, vous pouvez utiliser 39 caractères, mais si vous souhaitez simplement régler et oublier, 45).
$_SERVER['REMOTE_ADDR']
peut ne pas contenir réellement les adresses IP des clients réels, car il vous donnera une adresse proxy pour les clients connectés par l'intermédiaire d'un proxy, par exemple. Qui peut
bien être ce que vous voulez vraiment, cependant, en fonction de ce que vous faites avec L'IPs. L'adresse privée de QUELQU'un RFC1918 peut ne pas vous faire de bien si vous dites, en essayant de voir d'où votre trafic provient, ou en se rappelant quelle IP l'utilisateur s'est connecté en dernier lieu, où L'IP publique du proxy ou de la passerelle NAT pourrait être plus approprié pour stocker.
il existe plusieurs en-têtes HTTP comme X-Forwarded-For
qui peuvent ou non être définis par différents mandataires. Le problème est que ce sont simplement des en-têtes HTTP qui peuvent être définis par n'importe qui. Il n'y a pas de garantie quant à leur contenu. $_SERVER['REMOTE_ADDR']
est l'adresse IP physique réelle à laquelle le serveur web a reçu la connexion et à laquelle la réponse sera envoyée. Toute autre information est simplement arbitraire et volontaire. Il n'y a qu'un scénario que vous pouvez faire confiance à ces informations: vous contrôlez le mandataire qui définit cet en-tête. Ce n'est que si vous savez à 100% où et comment l'en-tête a été définie que vous devriez en tenir compte pour quelque chose d'important.
cela dit, Voici un exemple de code:
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'];
}
note de L'éditeur: utilisant le code ci-dessus a implications pour la sécurité . Le client peut définir toutes les informations D'en-tête HTTP (par ex. $_SERVER['HTTP_...
) pour toute valeur arbitraire qu'il veut. En tant que tel, il est beaucoup plus fiable d'utiliser $_SERVER['REMOTE_ADDR']
, car cela ne peut pas être définie par l'utilisateur.
de: http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html
voici un exemple de code plus propre d'une bonne façon d'obtenir l'ip de l'utilisateur.
$ip = $_SERVER['HTTP_CLIENT_IP']?$_SERVER['HTTP_CLIENT_IP']:($_SERVER['HTTP_X_FORWARDED_FOR']?$_SERVER['HTTP_X_FORWARDED_FOR']:$_SERVER['REMOTE_ADDR']);
Voici une version plus courte qui utilise l'opérateur elvis
$_SERVER['HTTP_CLIENT_IP']?:($_SERVER['HTTP_X_FORWARDED_FOR']?:$_SERVER['REMOTE_ADDR']);
Voici une version qui utilise isset pour supprimer les notices (merci, @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'];
il doit être contenu dans la variable $_SERVER['REMOTE_ADDR']
.
ma solution préférée est la façon dont Zend Framework 2 utilise. Il considère également les propriétés $_SERVER
HTTP_X_FORWARDED_FOR
, HTTP_CLIENT_IP
, REMOTE_ADDR
mais il déclare une classe pour qu'il définisse quelques mandataires de confiance et il renvoie une adresse IP pas un tableau. Je pense que c'est la solution qui s'en rapproche le plus:
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;
}
// [...]
}
voir le code complet ici: https://raw.githubusercontent.com/zendframework/zend-http/master/src/PhpEnvironment/RemoteAddress.php
il y a différents types d'utilisateurs derrière L'Internet, donc nous voulons attraper l'adresse IP à partir de potions différentes. Qui sont,
1. $_SERVER['REMOTE_ADDR']
-
Ceci contient l'adresse IP réelle du client. C'est la valeur la plus fiable que vous pouvez trouver de l'utilisateur.
2. $_SERVER['REMOTE_HOST']
-
Cela récupérera le nom D'hôte à partir duquel l'utilisateur visualise la page courante.
Mais pour que ce script fonctionne, Recherche de nom d'hôte à l'intérieur de httpd.conf doit être configuré.
3. $_SERVER['HTTP_CLIENT_IP']
-
Cela récupérera l'adresse IP lorsque l'utilisateur est à partir de services Internet partagés.
4. $_SERVER['HTTP_X_FORWARDED_FOR']
- cela va récupérer l'adresse IP de l'utilisateur quand il est derrière le proxy
pour que nous puissions utiliser cette fonction combinée suivante pour obtenir l'adresse IP réelle des utilisateurs qui regardent dans diffrent positions,
// 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;
}
C'est la méthode la plus avancée, j'ai trouvé, déjà essayé quelques autres dans le passé. Valide pour s'assurer d'obtenir l'adresse IP du visiteur (mais s'il vous plaît noter que tout hacker pourrait falsifier l'adresse ip facilement).
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 IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// check if multiple ips 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 since all else failed
return $_SERVER['REMOTE_ADDR'];
}
/**
* Ensures an ip address is both a valid IP 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 is set and not equivalent to 255.255.255.255
if ($ip !== false && $ip !== -1) {
// make sure to get unsigned long representation of ip
// 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;
}
source: http://blackbe.lt/advanced-method-to-obtain-the-client-ip-in-php /
La réponse est d'utiliser $_SERVER
à la variable. Par exemple, $_SERVER["REMOTE_ADDR"]
retournerait l'adresse IP du client.
C'est la méthode que j'utilise, et qu'il valide d'un IPv4 entrée:
// 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;
$ip = "";
if (!empty($_SERVER["HTTP_CLIENT_IP"]))
{
//check for ip from share 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;
comme tous les autres avant de pouvoir utiliser $_SERVER['REMOTE_ADDR'];
pour obtenir l'adresse IP du client.
en outre, si vous avez besoin de plus d'informations sur un utilisateur, vous pouvez utiliser ce:
<?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>";
?>
l'information plus spécifique du Client va dans $clientDetails.
Vous pouvez récupérer les éléments JSON stockés dans la variable $clientDetails de cette façon: $clientDetails->PostalCode/nom d'hôte/région/loc...
j'utilise ipinfo.io pour obtenir des informations supplémentaires.
j'espère que ça aidera.
j'aime ce codesnippet:
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');
}
Eh bien, cela peut être fait simplement en utilisant la variable GLOBAL
nommée comme $_SERVER
.
le $_SERVER
est un tableau dont les noms d'attribut sont REMOTE_ADDR
.
assignez-le comme ceci
$userIp = $_SERVER['REMOTE_ADDR'];
ou l'utiliser directement comme echo $_SERVER['REMOTE_ADDR'];
ou echo ($_SERVER['REMOTE_ADDR']);
la fonction suivante détermine toutes les possibilités et renvoie la valeur dans la virgule séparée (ip,ip, etc.).
il a aussi la fonction de validation optionnelle as (premier paramètre désactivé par défaut) pour valider l'adresse IP par rapport à (plage privée, et plage réservée).
<?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 contain 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;
}
}
cette fonction est compacte et vous pouvez l'utiliser partout. Mais !
n'oubliez pas ça ! Dans ce type de fonctions ou de blocs de code ne garantit pas d'enregistrer L'Utilisateur IP réelle parce que certains utilisateurs peuvent utiliser proxy ou d'autres passerelles en toute sécurité pour être invisible ou ne peut pas suivre
Fonction 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;
}
Utilisation :
$IP = GetIP();
ou directement GetIP();
function get_client_ip()
{
$ipaddress = '';
if (getenv('HTTP_CLIENT_IP'))
$ipaddress = getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED'))
$ipaddress = getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED'))
$ipaddress = getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR'))
$ipaddress = getenv('REMOTE_ADDR');
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
comme ça????
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;
}
tous les en-têtes commençant par' HTTP_ 'ou' X - ' peuvent être spoof respectivement est défini par l'utilisateur. Si vous voulez garder la trace, utilisez cooies, etc.
Voici une simple doublure
$ip = $_SERVER['HTTP_X_FORWARDED_FOR']?: $_SERVER['HTTP_CLIENT_IP']?: $_SERVER['REMOTE_ADDR'];
EDIT:
code ci-dessus peut retourner adresses réservées (comme 10.0.0.1), une liste d'adresses de tous les serveurs mandataires sur le chemin, etc. Pour traiter ces cas, utilisez le code suivant:
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();
Voici la version à une doublure qui reçoit L'adresse IP du client:
$ip = @$_SERVER['HTTP_CLIENT_IP'] ?: @$_SERVER['HTTP_X_FORWARDED_FOR'] ?: @$_SERVER['REMOTE_ADDR'];
Notes:
- en utilisant
@
, il supprime les notices PHP. -
valeur de
HTTP_X_FORWARDED_FOR
peut consister en plusieurs adresses séparées par une virgule, Donc si vous préférez obtenir la première, vous pouvez utiliser la méthode suivante:current(explode(',', @$_SERVER['HTTP_X_FORWARDED_FOR']))
Sécurité et avertissements extrait de conscience pour l'obtention de la propriété intellectuelle:
$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
$_SERVER['REMOTE_ADDR'];
exemple:
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'];
}