實踐使用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

所以:

  1. 有沒有X-Forwarded-For和代理服務器的設置有關;
  2. 正確與否也和代理服務器有關;

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的方法,他們是怎么封裝的呢?

koa中是如何封裝獲取客戶端IP的?

express中是如何處理IP的?

如有錯誤之處,望請斧正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM