跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Yii框架如何获取客户端IP_Yii框架真实IP地址获取【技巧】

Yii::app()->request->userHostAddress几乎总是错误的,因它仅读$_SERVER['REMOTE_ADDR'],在Nginx/CDN/SLB场景下返回代理内网IP;正确方式是配置ipHeaders和trustedHosts后使用getUserIP()。
Yii::app()->request->userHostAddress
拿到的几乎总是错的——它只读
$_SERVER['REMOTE_ADDR']
,在有 Nginx、CDN 或云 SLB 的场景下,这个值是上一跳代理的内网 IP(比如
10.0.1.5
),不是用户真实出口 IP。 必须主动配置可信代理和转发头,否则永远拿不到真实 IP。 Yii2 中 getUserIP() 为什么返回 127.0.0.1 或内网地址 这是最常被忽略的安全默认行为:
Yii2
的
getUserIP()
默认不信任任何代理,也不会解析
X-Forwarded-For
或
X-Real-IP
。它只看
REMOTE_ADDR
,而反向代理会把自身 IP 填进去。 确认你是否用了 Nginx:检查 Nginx 配置里有没有
proxy_set_header X-Real-IP $remote_addr;
或
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
确认云厂商用的头名:腾讯云用
Tencent-Cloud-Real-IP
,阿里云 SLB 默认用
X-Forwarded-For
,AWS ALB 用
X-Forwarded-For
,但需注意多级代理时该头可能含多个 IP 必须同时配
ipHeaders
和
trustedHosts
,缺一不可;只加头不设可信段,
getUserIP()
会直接忽略那些头 正确配置示例(
config/web.php
):
'request' => [ 'class' => 'yii\web\Request', 'ipHeaders' => ['X-Forwarded-For', 'X-Real-IP', 'Tencent-Cloud-Real-IP'], 'trustedHosts' => ['10.0.0.0/8', '192.168.0.0/16', '172.16.0.0/12'], ],
Yii2 获取真实 IP 的推荐写法:别直接用 userHostAddress
userHostAddress
是只读
REMOTE_ADDR
的快捷属性,完全绕过代理逻辑,等价于裸写
$_SERVER['REMOTE_ADDR']
。线上环境务必弃用。 统一走
$request->getUserIP()
,它会按
ipHeaders
顺序读头,并校验来源 IP 是否在
trustedHosts
内 如果需要兼容性更强的 fallback(比如某些 CDN 不传标准头),可手动补一层判断:
$ip = $request->getUserIP() ?: $request->getRemoteIP();
getRemoteIP()
是底层方法,返回未经代理校验的
REMOTE_ADDR
,仅作兜底,不能当主力 Yii3 使用 PSR-7 ServerRequest 时怎么取真实 IP Yii3 彻底移除了
getUserIP()
封装,所有逻辑得自己写。自由度高,但出错率也高——没人帮你校验代理是否可信。 WOC-YII开源站群管理系统1.3 WOC-YII是rschome.com基于yii framework 1.1.8框架所开发的一款开源简易站群管理系统。它的功能与WOC完全一样。目前版本为V1.3,新版本正在开发中,同时欢迎大家参与到开发中来! WOC-YII 1.3在1.2的基础上优化了登录系统(密码加密),优化了权限控制系统,新增seo管理功能,新增自动安装向导! 程序框架:yiiframework1.1.8 配置文件:p 下载 先读头:
$request->getHeaderLine('X-Forwarded-For')
(自动大小写不敏感) 拆出第一个非私有 IP:
array_filter(array_map('trim', explode(',', $xff)))
,再逐个用
filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
过滤 必须手写来源 IP 校验:
$clientIp = $request->getServerParams()['remote_addr'] ?? '127.0.0.1';
,然后判断它是否落在你的内网段(如
10.0.0.0/8
)内,只有可信来源才接受其转发的头 别忘了 fallback 到
$clientIp
——当所有头都为空或不可信时,这是唯一能用的值 调试 IP 获取失败的三个关键检查点 线上看到 IP 固定为
127.0.0.1
、
10.x.x.x
或空字符串,基本就卡在这三处。 Nginx(或 CDN)没转发 IP 头:用
curl -H "X-Real-IP: 1.2.3.4" http://your-site.com/test
手动测试头是否透传到底层 PHP
trustedHosts
没覆盖实际代理网段:比如 SLB 实际出口是
172.20.10.5
,但配置里只写了
192.168.0.0/16
,那头就被无视了 PHP 运行模式影响
$_SERVER
:FastCGI 下部分头可能被 Nginx 截断或重命名,检查
phpinfo()
页面里的
HTTP_X_REAL_IP
是否存在 真实 IP 获取不是“调一个函数就行”的事,它是网络链路、中间件配置、框架安全策略三者对齐的结果。少对一环,拿到的就是假 IP。

相关文章