nginx反向代理下thinkphp、php获取不到正确的外网ip

在记录用户发送短信需要获取用户ip时,tp一直获取的是内网ip:10.10.10.10

tp框架获取ip方法:get_client_ip

 1 /**
 2  * 获取客户端IP地址
 3  * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 4  * @param boolean $adv 是否进行高级模式获取(有可能被伪装)
 5  * @return mixed
 6  */
 7 function get_client_ip($type = 0,$adv=false) {
 8     $type       =  $type ? 1 : 0;
 9     static $ip  =   NULL;
10     if ($ip !== NULL) return $ip[$type];
11     if($adv){
12         if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
13             $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
14             $pos    =   array_search('unknown',$arr);
15             if(false !== $pos) unset($arr[$pos]);
16             $ip     =   trim($arr[0]);
17         }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
18             $ip     =   $_SERVER['HTTP_CLIENT_IP'];
19         }elseif (isset($_SERVER['REMOTE_ADDR'])) {
20             $ip     =   $_SERVER['REMOTE_ADDR'];
21         }
22     }elseif (isset($_SERVER['REMOTE_ADDR'])) {
23         $ip     =   $_SERVER['REMOTE_ADDR'];
24     }
25     // IP地址合法验证
26     $long = sprintf("%u",ip2long($ip));
27     $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
28     return $ip[$type];
29 }

View Code

因一些原因,w项目是在Apache下,后来另外一些项目挤进来使用了nginx,nginx下的项目需要也微信80端口授权,所以使用了反向代理。

经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址
tp框架自带函数获取的是$remote_addr,所以我们没办法获取真实ip。

打开/usr/local/reverse_proxy_nginx/conf/nginx.conf 可以看到如下关键配置

location / {proxy_pass http://backend2;#Proxy Settings
            proxy_redirect     off;proxy_set_header   Host             $host;proxy_set_header   X-Real-IP        $remote_addr;proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

测试

        $remoteaddr=$_SERVER["REMOTE_ADDR"];echo $remoteaddr;echo "---";$remotehost=$_SERVER["REMOTE_HOST"];echo $remotehost;echo "---";$xforwardedfor=$_SERVER["HTTP_X_FORWARDED_FOR"];echo $xforwardedfor;echo "---";$xrealip=$_SERVER["HTTP_X_REAL_IP"];echo $xrealip;  

输出

10.10.10.123------181.128.136.191---181.128.136.191

181.128.136.191便是你真实的外网ip,所以只需要获取HTTP_X_FORWARDED_FOR或者HTTP_X_REAL_IP就可以了。下面是修改后的tp框架函数ThinkPHP\Common\functions.php

 1 /*
 2 * 访问时用localhost访问的,读出来的是“::1”是正常情况。
 3 * ::1说明开启了ipv6支持,这是ipv6下的本地回环地址的表示。
 4 * 使用ip地址访问或者关闭ipv6支持都可以不显示这个。
 5 */
 6 function get_client_ip() {
 7     $ip = "unknown";
 8     if (isset($_SERVER)) {
 9         if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
10             $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
11         } elseif (isset($_SERVER["HTTP_CLIENT_ip"])) {
12             $ip = $_SERVER["HTTP_CLIENT_ip"];
13         } else {
14             $ip = $_SERVER["REMOTE_ADDR"];
15         }
16     } else {
17         if (getenv('HTTP_X_FORWARDED_FOR')) {
18             $ip = getenv('HTTP_X_FORWARDED_FOR');
19         } elseif (getenv('HTTP_CLIENT_ip')) {
20             $ip = getenv('HTTP_CLIENT_ip');
21         } else {
22             $ip = getenv('REMOTE_ADDR');
23         }
24     }
25     if(trim($ip)=="::1"){
26         $ip="127.0.0.1";
27     }
28     return $ip;
29 }

View Code

Apache下的tp项目,再调用get_client_ip函数就可正常获取外网ip了

posted on 2016-12-30 16:04 无影飞絮剑 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/itslives-com/p/X-Real-IP.html

nginx反向代理下thinkphp、php获取不到正确的外网ip相关推荐

  1. 多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...

  2. nginx反向代理后,java获取真实ip和解决request.getServerName()的问题

    1. nginx.conf的server下增加以下配置 #解决request.getServerName()的问题proxy_set_header Host $host:$server_port;pr ...

  3. Nginx反向代理负载均衡时,验证码不正确

    一.开门见山说,这是session失效的问题 nginx负载均衡导致session错误 在最近做的项目遇到一个坑,需求如下,到我的订单的时候判断了用户是否登录,如果没有登录就跳转到登录页面,登录之后在 ...

  4. C#获取路由器外网IP,MAC地址

    C#实现的获取路由器MAC地址,路由器外网地址.对于要获取路由器MAC地址,一定需要知道路由器web管理系统的用户名和密码.至于获取路由器的外网IP地址,可以不需要知道路由器web管理系统的用户名和密 ...

  5. uni-app——一种通过Nginx反向代理处理302重定向请求解决网络请求中无法获取Cookie的解决方案

    问题描述 小程序中不会自动保存和发送Cookie 使用插件(https://uniapp.dcloud.io/api/request/request)方法不能解决302重定向情况下获取Cookie 小 ...

  6. OSS在private权限下的无参数访问(Nginx反向代理实现)

    本文主要介绍内容 oss默认权限策略是private,当修改到public-read或更高权限时会提示存在安全风险.如果需要访问oss资源需要在地址上添加签名内容,不利于地址的存储和使用.本文会介绍如 ...

  7. nginx反向代理获取用户真实ip

    nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的 ...

  8. Nginx反向代理导致PHP获取不到正确的HTTP_HOST,SERVER_NAME,客户端IP的解决方法

    Nginx反向代理导致PHP获取不到正确的HTTP_HOST,SERVER_NAME,客户端IP的解决方法 参考文章: (1)Nginx反向代理导致PHP获取不到正确的HTTP_HOST,SERVER ...

  9. nginx 反向代理 某个目录下 带特定后缀名的文件

    因为现在前端开发有时开发环境和生产环境 url路径不同,所以前端基本会采用nginx反向代理接口 举个例子 想把http://localhost/project/test.action 反向代理到 h ...

最新文章

  1. adoquery查询结果如何赋给一个变量(delphi和c++ builder)
  2. 【C 语言】内存四区原理 ( 常量区示例 | 不同函数返回的相同字符串的指针地址相同 )
  3. 自定义滚动条Js简版
  4. 自由自在意式手工冰淇淋的清凉之风已“冰”临城下
  5. CVPR 2019开源论文 | Rob-GAN:生成器、鉴别器以及对抗攻击者
  6. linux5.4+resin4.0.14+jdk1.6+JDBC篇
  7. 浅谈嵌入式软件的未来发展
  8. 谈谈全自动安装常使用的pip install的原理及作用!!!
  9. mfc 子窗体任何消息都不触发_你不知道的 WebSocket
  10. PTA 基础编程题目集 (参考代码)
  11. c语言考试题库大一下学期基础,c语言考试题(全国c语言二级考试题库)
  12. java基于springboot的酒店预约管理平台系统
  13. 210所高校21届保研率曝光!这些211保研率堪比985!
  14. Java.MapReduce处理全国各省市疫情数据,上传Hadoop平台处理后的数据
  15. weiui使用jquery infinite无限滚动加载,数据重复自执行
  16. 感谢一路上有你们的陪伴
  17. push to origin/dev was rejected
  18. 怎么在Ubuntu手机上发送短信及拨打电话
  19. 洛谷P1966 火柴排队
  20. MySQL修改字段、修改表索引等操作

热门文章

  1. 人工智阅读理解能力首超人类,阿里巴巴刷新世界纪录
  2. 给PUBG Mobile打上几十个数据标签解析霸榜原因
  3. 硬核塔防策略手游《明日方舟》体验分析
  4. VR游戏开发者如何避免“移动引起眩晕”
  5. RESET MASTER 和RESET SLAVE 命令的使用方法 注意事项
  6. linux系统中的目录讲解
  7. 在linux学习中遇到的问题
  8. Hdu1232 畅通工程 【并查集】
  9. Extjs4 radiogroup打开时的被选中值设置为变量
  10. PHP只下载不打开文件