php 如何在 Laravel 5+ 中获取客户端 IP 地址
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33268683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get client IP address in Laravel 5+
提问by Amrinder Singh
I am trying to get the client's IP address in Laravel.
我正在尝试在 Laravel 中获取客户端的 IP 地址。
It is easy to get a client's IP in PHP by using $_SERVER["REMOTE_ADDR"]
. It is working fine in core PHP, but when I use the same thing in Laravel, it returns the server IP instead of the visitor's IP.
使用 .php 可以很容易地在 PHP 中获取客户端的 IP $_SERVER["REMOTE_ADDR"]
。它在核心 PHP 中运行良好,但是当我在 Laravel 中使用相同的东西时,它返回服务器 IP 而不是访问者的 IP。
回答by samlev
Looking at the Laravel API:
查看Laravel API:
Request::ip();
Internally, it uses the getClientIps
method from the Symfony Request Object:
在内部,它使用getClientIps
来自Symfony 请求对象的方法:
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);
}
回答by Sebastien Horin
If you are under a load balancer, Laravel's \Request::ip()
alwaysreturns the balancer's IP:
如果你在负载均衡器下,Laravel\Request::ip()
总是返回均衡器的 IP:
echo $request->ip();
// server ip
echo \Request::ip();
// server ip
echo \request()->ip();
// server ip
echo $this->getIp(); //see the method below
// clent ip
This custom method returns the real client ip:
此自定义方法返回真实的客户端 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;
}
}
}
}
}
In addition to this I suggest you to be very careful using Laravel's throttlemiddleware: It uses Laravel's Request::ip()
as well, so all your visitors will be identified as the same user and you will hit the throttle limit very quickly. I experienced this live and this caused big issues.
除此之外,我建议您在使用 Laravel 的油门中间件时要非常小心:它也使用 Laravel 的中间件Request::ip()
,因此您的所有访问者都将被识别为同一用户,并且您将很快达到油门限制。我现场体验了这件事,这引起了大问题。
To fix this:
要解决此问题:
Illuminate\Http\Request.php
照亮\Http\Request.php
public function ip()
{
//return $this->getClientIp(); //original method
return $this->getIp(); // the above method
}
You can now also use Request::ip()
, which should return the real IP in production.
您现在还可以使用Request::ip()
,它应该返回生产中的真实 IP。
回答by Stan Smulders
Use request()->ip()
.
使用request()->ip()
.
From what I understand, since Laravel 5 it's advised/good practice to use the global functions like:
据我了解,从 Laravel 5 开始,建议/好的做法是使用全局函数,例如:
response()->json($v);
view('path.to.blade');
redirect();
route();
cookie();
And, if anything, when using the functions instead of the static notation my IDE doesn't light up like a Christmas tree.
而且,如果有的话,当使用函数而不是静态符号时,我的 IDE 不会像圣诞树一样亮起来。
回答by shalini
Add namespace
添加命名空间
use Request;
Then call the function
然后调用函数
Request::ip();
回答by Todor Todorov
For Laravel 5 you can use the Request object. Just call its ip()
method, something like:
对于 Laravel 5,您可以使用 Request 对象。只需调用它的ip()
方法,例如:
$request->ip();
回答by Govind Samrow
In Laravel 5
在 Laravel 5
public function index(Request $request) {
$request->ip();
}
回答by Yevgeniy Afanasyev
There are two things to take care of:
有两件事需要注意:
Get a helper function that returns a
Illuminate\Http\Request
and call the->ip()
method:request()->ip();
Think of your server configuration, it may use a proxy or
load-balancer
, especially in an AWS ELB configuration.
获取一个返回 a 的辅助函数
Illuminate\Http\Request
并调用该->ip()
方法:request()->ip();
想想您的服务器配置,它可能使用代理或
load-balancer
,尤其是在 AWS ELB 配置中。
If this is your case you need to follow "Configuring Trusted Proxies" or maybe even set a "Trusting All Proxies" option.
如果是这种情况,您需要遵循“配置受信任的代理”或者甚至设置“信任所有代理”选项。
Why? Because being your server will be getting your proxy/load-balancer
IP instead.
为什么?因为成为您的服务器将获得您的代理/ load-balancer
IP。
If you are on the AWS balance-loader, go to App\Http\Middleware\TrustProxies
and make $proxies
declaration look like this:
如果您在 AWS balance-loader 上,请转到App\Http\Middleware\TrustProxies
并进行如下$proxies
声明:
protected $proxies = '*';
Now test it and celebrate because you just saved yourself from having trouble with throttle middleware. It also relies on request()->ip()
and without setting "TrustProxies" up, you could have all your users blocked from logging in instead of blocking only the culprit's IP.
现在测试它并庆祝一下,因为您刚刚避免了油门中间件的麻烦。它还依赖于request()->ip()
和不设置“TrustProxies”,您可以阻止所有用户登录,而不是仅阻止罪魁祸首的 IP。
And because throttle middleware is not explained properly in the documentation, I recommend watching "laravel 5.2 tutorial for beginner, API Rate Limiting"
并且由于文档中没有正确解释油门中间件,我建议观看“ laravel 5.2 初学者教程,API 速率限制”
Tested in Laravel 5.7
在 Laravel 5.7 中测试
回答by Soura Sankar Ghosh
If you call this function then you easily get the client's IP address. I have already used this in my existing project:
如果你调用这个函数,那么你很容易得到客户端的 IP 地址。我已经在我现有的项目中使用了它:
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;
}
回答by Shadrix
If you are still getting 127.0.0.1 as the IP, you need to add your "proxy", but be aware that you have to change it before going into production!
如果您仍然获得 127.0.0.1 作为 IP,则需要添加您的“代理”,但请注意,您必须在投入生产之前对其进行更改!
Read "Configuring Trusted Proxies".
阅读“配置可信代理”。
And add this:
并添加这个:
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies = '*';
Now request()->ip()
gives you the correct IP.
现在request()->ip()
给你正确的IP。
回答by Vahid Alvandi
In Laravel 5.4 we can't call ip static. This a correct way to get the IP of the user:
在 Laravel 5.4 中我们不能调用 ip static。这是获取用户IP的正确方法:
use Illuminate\Http\Request;
public function contactUS(Request $request)
{
echo $request->ip();
return view('page.contactUS');
}