如何在Laravel 5+中获取客户端IP地址?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Laravel 5+中获取客户端IP地址?相关的知识,希望对你有一定的参考价值。
我想在Laravel中获取客户端的IP地址。众所周知,使用$_SERVER["REMOTE_ADDR"]
在php中获取客户端的IP要容易得多。
它在核心PHP中运行良好,但是当我在Laravel中使用相同的东西时,它会提供服务器IP而不是访问者IP。
看着Laravel API:
Request::ip();
在内部,它使用getClientIps
中的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);
}
如果您调用此功能,则可以轻松获取客户端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;
}
有两件事需要照顾
1)得到辅助函数,返回一个IlluminateHttpRequest
并调用->ip()
方法。
request()->ip();
2)想想你的服务器配置,它可能会使用proxy
或load balancer
(特别是在AWS ELB
配置中)
如果这是你的情况,你需要Configuring Trusted Proxies或甚至可能设置一个Trusting All Proxies
option。
为什么?
因为作为您的服务器将获得代理/平衡加载器IP。
怎么样?
如果你不是AWS balance-loader
去AppHttpMiddlewareTrustProxies
并使$proxies
声明看起来像这样:
protected $proxies = '*';
现在测试并庆祝,因为你刚刚从throttle middleware
遇到麻烦。它还依赖于request()->ip()
并且没有设置TrustProxies
,你可以阻止所有用户登录而不是仅阻止罪魁祸首的IP。
因为在文档中没有正确解释throttle middleware
,我建议观看this video
在Laravel 5.7中测试过
当我们想要用户的ip_address
时:
$_SERVER['REMOTE_ADDR']
并希望服务器地址:
$_SERVER['SERVER_ADDR']
使用request()->ip()
从Laravel 5开始(根据我的理解)建议/良好实践使用全局函数,如:
response()->json($v);
view('path.to.blade');
redirect();
route();
cookie();
你明白了这一点:-)如果有的话,当使用这些函数(而不是静态的notarion)时,我的IDE就不会像圣诞树一样;-)
If you are under a load balancer
Laravel的Request::ip()
总是返回平衡器的IP
echo $request->ip();
// server ip
echo Request::ip();
// server ip
echo
equest()->ip();
// server ip
echo $this->getIp(); //see the method below
// clent 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;
}
}
}
}
}
更多:如果您使用Laravel的油门中间件
除此之外,我建议你使用Laravel的油门中间件要非常小心:它也使用Laravel的Request::ip()
,所以你的所有访客都将被识别为同一个用户,你很快就会达到油门限制。在现场体验......这让我遇到了大问题......
解决这个问题:
照亮 HTTP Request.php
public function ip()
{
//return $this->getClientIp(); //original method
return $this->getIp(); // the above method
}
您现在也可以使用Request::ip()
,它应该返回生产中的真实IP
添加命名空间
use Request;
然后调用该函数
Request::ip();
对于Laravel 5,您可以使用Request对象。只需调用其ip()方法即可。就像是:
$request->ip();
在Laravel 5
public function index(Request $request) {
$request->ip();
}
如果您仍然获得127.0.0.1作为IP,则需要添加“代理”。
但要注意,你必须在生产前改变它!
阅读本部分:https://laravel.com/docs/5.7/requests#configuring-trusted-proxies
现在只需添加:
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies = '*';
现在请求() - > ip()为您提供正确的IP
在版本laravel 5.4中我们无法调用ip static这是获取ip用户的正确方法
use IlluminateHttpRequest;
public function contactUS(Request $request)
{
echo $request->ip();
return view('page.contactUS');
}
如果您想要客户端IP并且您的服务器位于aws elb之后,请使用以下代码。测试laravel 5.3
$elbSubnet = '172.31.0.0/16';
Request::setTrustedProxies([$elbSubnet]);
$clientIp = $request->ip();
以上是关于如何在Laravel 5+中获取客户端IP地址?的主要内容,如果未能解决你的问题,请参考以下文章