Ich versuche, die IP-Adresse des Kunden in Laravel zu erhalten. Wie wir alle wissen, ist es viel einfacher, die IP-Adresse eines Clients in PHP zu erhalten, indem $_SERVER["REMOTE_ADDR"]
verwendet wird.
Es funktioniert gut in Core PHP, aber wenn ich dasselbe in Laravel verwende, dann gibt es Server-IP anstelle von Besucher-IP.
Betrachten der Laravel API :
Request::ip();
Intern verwendet es die getClientIps
-Methode aus dem 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);
}
Verwenden Sie request()->ip()
Seit Laravel 5 ist es (nach meinem Verständnis) ratsam, die globalen Funktionen zu verwenden, wie:
response()->json($v);
view('path.to.blade');
redirect();
route();
cookie();
Sie verstehen den Punkt :-) Und wenn überhaupt, wenn Sie die Funktionen verwenden (anstelle des statischen Notars), ist meine IDE nicht wie ein Weihnachtsbaum ;-)
Laravel's \Request::ip()
always gibt die IP des Balancers zurück
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;
}
}
}
}
}
Darüber hinaus empfehle ich Ihnen, mit der DrosselMiddleware von Laravel sehr vorsichtig zu sein: Sie verwendet auch die Request::ip()
der Laravel, sodass alle Ihre Besucher als derselbe Benutzer identifiziert werden und Sie sehr schnell das Gaslimit erreichen. Live erlebt ... das führte mich zu großen Problemen ...
Um das zu beheben:
Illuminate\Http\Request.php
public function ip()
{
//return $this->getClientIp(); //original method
return $this->getIp(); // the above method
}
Sie können jetzt auch Request::ip()
verwenden, die die reale IP in der Produktion zurückgeben soll
Namespace hinzufügen
use Request;
Dann rufen Sie die Funktion auf
Request::ip();
Für Laravel 5 können Sie das Request-Objekt verwenden. Rufen Sie einfach die Methode ip () auf.
$request->ip();
In Laravel 5
public function index(Request $request) {
$request->ip();
}
in version laravel 5.4 können wir ip static nicht als korrekten Weg bezeichnen, um ip user zu bekommen
use Illuminate\Http\Request;
public function contactUS(Request $request)
{
echo $request->ip();
return view('page.contactUS');
}
Wenn Sie eine Client-IP wünschen und sich Ihr Server hinter aws elb befindet, geben Sie den folgenden Code ein. Getestet auf Laravel 5.3
$elbSubnet = '172.31.0.0/16';
Request::setTrustedProxies([$elbSubnet]);
$clientIp = $request->ip();
Es gibt zwei Dinge, auf die man achten muss
1) Ruft die Hilfsfunktion ab, die eine Illuminate\Http\Request
zurückgibt, und ruft die ->ip()
-Methode auf.
request()->ip();
2) Denken Sie an Ihre Serverkonfiguration, sie kann proxy
oder load balancer
verwenden (insbesondere in AWS ELB
config).
Wenn dies Ihr Fall ist, müssen Sie Vertrauenswürdige Proxies konfigurieren oder sogar eine Trusting All Proxies
-Option festlegen.
Warum?
Weil Ihr Server stattdessen Ihre Proxy-/Balance-Loader-IP erhält.
Wie?
Wenn Sie kein AWS balance-loader
sind
Gehe zu App\Http\Middleware\TrustProxies
und $proxies
-Deklaration folgendermaßen aussehen:
protected $proxies = '*';
Testen Sie es jetzt und feiern Sie, denn Sie haben sich gerade vor throttle middleware
gerettet. Es ist auch auf request()->ip()
angewiesen und ohne TrustProxies
einzustellen, könnten Sie alle Ihre Benutzer von der Anmeldung blockieren lassen, anstatt nur die IP des Täters zu blockieren.
Und weil throttle middleware
in der Dokumentation nicht richtig erklärt wird, empfehle ich mir dieses Video
In Laravel getestet 5.7
Wenn Sie immer noch 127.0.0.1 als IP erhalten, müssen Sie Ihren "Proxy" hinzufügen.
Aber Achtung, Sie müssen es ändern, bevor Sie mit der Produktion beginnen !!
Lesen Sie diesen Teil: https://laravel.com/docs/5.7/requests#configuring-trusted-proxies
Und jetzt fügen Sie einfach folgendes hinzu:
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies = '*';
Request () -> ip () gibt Ihnen jetzt die richtige IP
Wenn Sie diese Funktion aufrufen, erhalten Sie leicht die Client-IP-Adresse . Ich habe diesen nützlichen Code bereits in meinem vorhandenen Projekt verwendet.
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;
}