实践使用nodejs获取用户真实IP?
先上代码
var http = require('http')
var server = http.createServer(function (req,res) {
console.log(req.headers['x-forwarded-for'] ); // 判断是否有反向代理
console.log(req.socket.remoteAddress ); // 判断后端的 socket 的 IP
let ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress
res.end(ip)
})
server.listen('9098')
x-forwarded-for是什么?
X-Forwarded-For 是一个扩展header头,用来表示 HTTP 请求端真实 IP,在HTTP/1.1(RFC 2616)协议中没有定义,但是现在已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension)标准之中。
由人为设置
一些代理服务器会设置一些消息头,比如nginx会在转发请求的时候可以带上这个消息头,向应用服务传递客户端的真实IP;
使用下面的配置在nginx设置反向代理转发的X-Forwarded-For:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; // 常用
proxy_set_header X-Forwarded-For "$http_x_forwarded_for, $remote_addr" // 不常用,$http_x_forwarded_for是读取到的消息头,如果请求头没有x-Forwarded-for,这个值就是空的。
这样就能在应用服务器拿到消息头 X-Forwarded-For;
可以伪造
因为是人为设置,伪造一个假的很简单,如下:
proxy_set_header X-Forwarded-For "121.12.12.12";
所以接收到的不可信任的服务器传递回来的header,或者客户端伪造了header,其中x-forwarded-for是不能当做客户端IP的。
格式
X-Forwarded-For请求头格式非常简单,就这样:X-Forwarded-For:client, proxy1, proxy2
,由[英文逗号+空格]隔开的多个部分组成,最开始的是离服务端最远的设备IP,然后是每一级代理的IP。
如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,代理服务器会把前一个网络设备的IP地址追加到X-Forwarded-For 上面,经过层层追加,服务端最终会收到以下信息:
X-Forwarded-For: IP0, IP1, IP2
同时注意到IP3是不会追加上到这个列表上的。
实际验证:在本地电脑开启一个nodejs服务,端口为9090;开启nginx反向代理,端口为8062;
- 通过8062访问nginx服务的时候,req.headers['x-forwarded-for']值为
192.168.1.105 //nginx通过X-Forwarded-For将客户端的地址转发了过来
- 通过9090直接访问nodejs访问,req.headers['x-forwarded-for']值为
undefined //直接请求的时候,没有设置消息头,自然为undefined
所以:
- 有没有X-Forwarded-For和代理服务器的设置有关;
- 正确与否也和代理服务器有关;
remoteAddress
如果没有X-Forwarded-For,应用服务器可以通过与服务端建立 TCP 连接获取到。在nodejs中可以通过req.socket.remoteAddress获取到IP3;
remoteAddress有没有可能是假的呢?因为tcp链接需要三次握手,所以无法伪造这个ip。
X-Real-IP是什么
是一个自定义的消息头,目前并不属于任何标准,完全由用户控制。
结论;
没有代理:直接使用remoteAddress获取客户端IP,因为header中x-forwarded-for不可靠,可能有也可能没有,甚至可能是伪造的;
有代理的情况下,获取到的remoteAddress是代理服务器的IP,如果代理服务器是可信赖的,那么能通过x-forwarded-for来获取客户端IP。
在express,koa中都有获取ip的方法,他们是怎么封装的呢?
如有错误之处,望请斧正。
实践使用nodejs获取用户真实IP?的更多相关文章
- PHP获取用户真实 IP , 淘宝IP接口获得ip地理位置(转)
<?php /** * 获取用户真实 IP */ function getIP() { static $realip; if (isset($_SERVER)){ if (isset($_SER ...
- java 获取用户真实ip
/** * 获取用户真实ip * @param request * @return */ public static String getIpAddr(HttpServletRequest reque ...
- 多层代理获取用户真实IP
1. 几个概念remote_addr:如果中间没有代理,这个就是客户端的真实IP,如果有代理,这就是上层代理的IP.X-Forwarded-For:一个HTTP扩展头,格式为 X-Forwarded- ...
- Java中使用HttpRequest获取用户真实IP地址端口
import javax.servlet.http.HttpServletRequest; /** * 自定义访问对象工具类 * * 获取对象的IP地址等信息 * @author X-rapido * ...
- 在有nginx做反向代理时候,如何获取用户真实Ip信息
在获取用户的Ip地址时,不一定可以获取到用户真实的地址信息,这要看代理服务器的类型,代理服务器有普通匿名代理服务器,高匿代理服务器,像这种情况很难获取到用户真实的Ip地址 假如用户没有使用匿名代理服务 ...
- 获取用户真实IP:(模拟:客户端--F5--nginx--tomcat 后端获取用户真实IP)
模拟:客户端--F5--nginx--tomcat 后端获取用户真实IP 192.168.109.137 :nginx01(充当第一层代理==F5)192.168.109.138 :nginx02(二 ...
- 如何根据HttpServletRequets获取用户真实IP地址
最近的一个项目的某个功能获取用户的ip地址,添加用户的系统使用记录. 我发现当我直接使用getRemoteAddr()方法从HttpServletRequet中获取用户的ip时,获取到的是服务器的ip ...
- nginx反向代理获取用户真实ip
nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的 ...
- CDN下nginx获取用户真实IP地址
随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户 ...
随机推荐
- .Net Core踩坑记:读取txt中文乱码
迁移.net framework的项目,有块读取txt中文转码的问题,普通的不能再普通的代码,想都没想直接copy过去,也没测,结果今天就被坑了.Core是3.1版本,这是原来的代码: string ...
- JS中函数执行顺序的问题?
作者:知乎用户链接:https://www.zhihu.com/question/23564807/answer/82996422来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- gerapy 爬虫web调度可视化工具(基于scrapyd)
web 基于scrapyd 提供主机管理功能 基于scrapyd管理已安装服务的主机. 进入具体主机管理页面,会自动加载所有已知爬虫任务: 可直接可以调度.运行.查看日志. 提供项目管理功能 将已知项 ...
- django python mange.py runserver 源码
django python mange.py runserver 源码 入 口 mange.py文件 execute_from_command_line函数 输入参数为['manage.py', 'r ...
- IIS 发布页面后或者vs平台运行后显示“未能加载文件或程序集“WebApi”或它的某一个依赖项。试图加载格式不正确的程序。”
一般情况下出现这样的问题是因为.dll文件不存在或者路径不正确. 但今天我遇到的情况都不在这两个内. 我确定.dll文件是存在的,路径也是正确的. 但是程序死活都是“未能加载文件或程序集“xxx”或它 ...
- RocketMQ入门到入土(二)事务消息&顺序消息
接上一篇:RocketMQ入门到入土(一)新手也能看懂的原理和实战! 一.事务消息的由来 1.案例 引用官方的购物案例: 小明购买一个100元的东西,账户扣款100元的同时需要保证在下游的积分系统给小 ...
- HTTP 协议详解(二)
前面一篇已经说过了 HTTP 的基本特性,HTTP 的发展史,前情回顾.这一篇就更详细的 HTTP 协议使用过程一些参数配置,缓存,Cookie设置相关的细节做一些梳理. 数据类型与编码 在 TCP/ ...
- 收藏python开发各种资源官方文档
http://json.cn/ https://cn.bing.com/ https://processon.com/ https://docs.djangoproject.com/en/1.11/r ...
- Spring Security(三) —— 核心配置解读
摘要: 原创出处 https://www.cnkirito.moe/spring-security-3/ 「老徐」欢迎转载,保留摘要,谢谢! 3 核心配置解读 上一篇文章<Spring Secu ...
- Python3笔记011 - 3.2 选择语句
第3章 流程控制语句 3.2 选择语句 1.if语句 if 表达式: 语句块 执行的流程是:当表达式的布尔值为真时,执行语句块,为假时,离开if语句,程序往下执行. 2.if...else语句 if ...