J'essaie d'obtenir l'adresse IP du client à Laravel. Comme nous le savons tous, il est beaucoup plus facile d'obtenir l'adresse IP d'un client dans PHP en utilisant $_SERVER["REMOTE_ADDR"]
.
Cela fonctionne très bien dans le noyau PHP, mais quand j'utilise la même chose dans Laravel, cela donne l'IP du serveur au lieu de l'IP du visiteur.
En regardant l'API Laravel :
Request::ip();
En interne, il utilise la méthode getClientIps
de Symfony Request Object :
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);
}
Utilisez request()->ip()
Depuis Laravel 5, il est (d'après ce que j'ai compris) conseillé/bonne pratique d'utiliser les fonctions globales telles que:
response()->json($v);
view('path.to.blade');
redirect();
route();
cookie();
Vous obtenez le point :-) Et si quelque chose, en utilisant les fonctions (au lieu du notarion statique) mon IDE ne s'allume pas comme un arbre de Noël ;-)
\Request::ip()
toujours de Laravel retourne l'adresse IP de l'équilibreur
echo $request->ip();
// server ip
echo \Request::ip();
// server ip
echo \request()->ip();
// server ip
echo $this->getIp(); //see the method below
// clent 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;
}
}
}
}
}
En plus de cela, je vous suggère de faire très attention en utilisant le middleware accélérateur de Laravel: il utilise également la Request::ip()
de Laravel, de sorte que tous vos visiteurs seront identifiés comme étant le même utilisateur et que vous atteindrez très rapidement la limite des accélérateurs rapidement. Expérimenté en live ... cela m'a conduit à de gros problèmes ...
Pour résoudre ce problème:
Illuminer\Http\Request.php
public function ip()
{
//return $this->getClientIp(); //original method
return $this->getIp(); // the above method
}
Vous pouvez maintenant aussi utiliser Request::ip()
, qui devrait retourner la vraie IP en production
Ajouter un espace de noms
use Request;
Puis appelez la fonction
Request::ip();
À Laravel 5
public function index(Request $request) {
$request->ip();
}
dans la version laravel 5.4, nous ne pouvons pas appeler ip statique ceci une façon correcte d'obtenir l'utilisateur ip
use Illuminate\Http\Request;
public function contactUS(Request $request)
{
echo $request->ip();
return view('page.contactUS');
}
Si vous voulez une adresse IP client et que votre serveur est derrière aws elb, utilisez le code suivant. Testé pour laravel 5.3
$elbSubnet = '172.31.0.0/16';
Request::setTrustedProxies([$elbSubnet]);
$clientIp = $request->ip();
Il y a 2 choses à prendre en charge
1) obtient une fonction d'assistance qui retourne un Illuminate\Http\Request
et appelle la méthode ->ip()
.
request()->ip();
2) Pensez à la configuration de votre serveur, il peut utiliser proxy
ou load balancer
(en particulier dans AWS ELB
config)
Si tel est votre cas, vous devez Configuration des proxy approuvés ou peut-être même définir une Trusting All Proxies
option.
Pourquoi?
Parce qu'être votre serveur, vous obtiendrez à la place votre IP proxy/balance-loader.
Comment?
Si vous n'êtes pas AWS balance-loader
Aller au App\Http\Middleware\TrustProxies
et donnez la déclaration $proxies
à ceci:
protected $proxies = '*';
Maintenant testez-le et soyez heureux, car vous venez de vous éviter d'avoir des problèmes avec throttle middleware
. Il s'appuie également sur request()->ip()
et sans configurer TrustProxies
, tous vos utilisateurs pourraient ne pas pouvoir se connecter au lieu de ne bloquer que l'adresse IP du coupable.
Et comme throttle middleware
n'est pas expliqué correctement dans la documentation, je vous recommande de regarder cette vidéo
Testé à Laravel 5.7
Si vous obtenez toujours 127.0.0.1 en tant qu'IP, vous devez ajouter votre "proxy".
Mais attention, il faut le changer avant de commencer la production !!
Lisez cette partie: https://laravel.com/docs/5.7/requests#configuring-trusted-proxies
Et maintenant, ajoutez simplement ceci:
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies = '*';
Maintenant request () -> ip () vous donne l'adresse IP correcte
Si vous appelez cette fonction, vous obtenez facilement l'adresse IP du client . J'ai déjà utilisé ce code utile dans mon projet existant.
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;
}