zoukankan      html  css  js  c++  java
  • 多级nginx代理,获取客户端真实ip

    今天服务里的微信公众号支付业务突然不能用了,报错为网络环境未能通过安全验证,请稍后再试。检查后端日志,没有任何问题,看来是成功创建支付订单,但是调起支付时出现了问题。上网查了一下,这个报错的直接原因是传入的客户端ip与调起支付的ip不符。但是印象中我在代码中获取的是X-Forwarded-For,就是请求来源的客户端IP,就查看日志发现传给微信的ip为172.17.0.1,也就是宿主机ip,这是才恍然大悟,在升级线上环境时我们将所有服务放进了docker,并且在docker里装了nginx来分发请求给对应的服务,也就是说我们是两级nginx代理,我们的服务是没法拿到最外层客户端ip的。只好改进nginx将每级代理的ip都记录起来,而不是直接覆盖。

    改进方法:

    对第一级nginx代理

    location ~ ^/test {
      proxy_pass http://127.0.0.1:8888;
      proxy_set_header Host $host;
      proxy_set_header X-real-ip $remote_addr;
      proxy_set_header X-Forwarded-For $remote_addr;
    }

    第一级nginx代理不需要改动,直接将原始客户端ip记录到X-Forwarded-For即可

    对于第二级,以及之后可能存在的更多级代理

    location ~ ^/test {
      proxy_pass http://127.0.0.1:12000;
      proxy_set_header Host $host;
      proxy_set_header X-real-ip $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    这样就将新一级代理的ip接到X-Forwarded-For的尾部,并用逗号分割。也就是说X-Forwarded-For是一个逗号拼接的ip字符串,想拿到原始ip只需要按逗号分割,取第一位ip即可。

    Golang业务中读取原始客户端ip代码

    	real_ip := r.Header.Get("X-Forwarded-For")
    	ip_list := strings.Split(real_ip, ",")
    	if len(ip_list) > 1 {
    		real_ip = ip_list[0]
    	}
    

    就是这么简单啦,希望对大家有所帮助~

  • 相关阅读:
    记录下IE7下的input标签bug
    CYQ.Data 轻量数据访问层(一) 概述
    网站安装打包 软件环境检测与安装[二] 上
    记录下关于调用RAR解压缩的问题
    CYQ.Data 轻量数据访问层(六) 构造数据表
    记绕过路由封杀问题
    MapXtreme 2005 学习心得 一些问题(八)
    网站安装打包 修改app.config[六]
    关于控件导出Excel格式问题的新解决方案
    CYQ.Data 轻量数据访问层(二) 构造数据单元(上)
  • 原文地址:https://www.cnblogs.com/baiyb/p/9657233.html
Copyright © 2011-2022 走看看