想過用js獲取信息標識用戶機器嗎股冗?獲取本地ip?mac地址和蚪?
通過一番探索結(jié)論如下:
一止状、 mac地址不用想了。
二攒霹、 獲取ip
我們知道nginx的配置X-Forwarded-For
后端可以拿到ip
怯疤,這個ip是出口ip,標識不了訪問者機器
location /api {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300;client_max_body_size 30m;
rewrite ^/wisbayar_api(.*)$ $1 break;
proxy_pass http://xx.xx.xx.xx:11001/;
}
三催束、利用webrtc
網(wǎng)頁即時通信 功能 實現(xiàn)點對點
通信集峦,獲取ip,我們看代碼如下抠刺。
function findIP(onNewIP) {
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}),
noop = function() {},
localIPs = {},
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key;
function ipIterate(ip) {
if (!localIPs[ip]) onNewIP(ip);
localIPs[ip] = true;
}
pc.createDataChannel("");
pc.createOffer(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(ipIterate);
});
pc.setLocalDescription(sdp, noop, noop);
}, noop);
pc.onicecandidate = function(ice) {
console.log('ice.candidate', ice.candidate)
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
};
}
function addIP(ip) {
console.log('got ip: ', ip);
}
findIP(addIP)
上面的代碼提到的概念有點多塔淤,我們通過代碼逐步看一下點對點通信概念:
new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}),
先看這里
iceServers
是什么?
ICE(Interactive Connectivity Establishment)
:是一個框架速妖,允許您的 Web 瀏覽器 (一個Peer A)與對等方(另一個Peer B)連接,它需要繞過阻止打開連接的防火墻,內(nèi)網(wǎng)限制高蜂。如果您的路由器不允許您直接與對等方連接,則通過服務器中繼數(shù)據(jù)罕容。 而ICE
使用STUN
/TURN
的一些技術(shù)來實現(xiàn)此目的
實現(xiàn)點對點
通信备恤,實例名取RTCPeerConnection
,就好理解了锦秒。代碼里的
stun.l.google.com:19302
是什么露泊?
這是google的STUN
服務器。這里還有很多公益的免費的可以查看:其他公共STUN 或 TURN 服務器
當然如果你要做自己的視頻功能脂崔,你也可以替換為自己的服務滤淳。
如果我們這里不寫這個
STUN
服務器,在pc.onicecandidate
中打印ice.candidate. address
可以看到 是一個以.local
結(jié)尾的字符串而不是自己想要的IP砌左。
- 那
STUN
服務器干了什么呢脖咐?
STUN(Session Traversal Utilities for NAT )
是一種協(xié)議铺敌。客戶端將向 Internet 上的 STUN 服務器發(fā)送請求屁擅,該服務器將回復客戶端的公共IP以及客戶端是否可以在NAT
后面訪問
NAT
是什么偿凭?
NAT(Network Address Translation)
:為設備提供公共IP
地址,俗稱路由器派歌。 給局域網(wǎng)內(nèi)部分配內(nèi)網(wǎng)地址弯囊,對外就使用它的公共IP
地址。
但是胶果,某些路由器對誰可以連接到網(wǎng)絡上的設備有限制匾嘱,即使我們有STUN
服務器找到的公共IP
地址,也不是任何人都可以創(chuàng)建連接早抠。在這種情況下霎烙,我們需要轉(zhuǎn)向TURN
。再看
TURN
是什么蕊连?
TURN(Traversal Using Relays around NAT)
:圍繞 NAT 使用中繼遍歷悬垃,實際上就是NAT
路由器限制了不能直連,就使用TURN
服務器來中轉(zhuǎn)轉(zhuǎn)發(fā)甘苍,是一種降級方式尝蠕。
結(jié)合上面的圖,現(xiàn)在我們就明白了载庭,為了實現(xiàn)無延遲看彼,實時通信,就要通過繞過
NAT
的限制囚聚,達到直連機器的目的闲昭。如果不能直連,就使用TURN
中轉(zhuǎn)靡挥。
STUN
服務器是用來取外網(wǎng)地址的。
TURN
服務器是在P2P(點對點)失敗時進行轉(zhuǎn)發(fā)的
- 代碼里
pc.createDataChannel
,pc.createOffer
是什么意思鸯绿?
pc.createDataChannel
是創(chuàng)建了一個數(shù)據(jù)通道跋破,這是在建立連接之前交換信息的通信渠道。需要需要交換的信息是一端發(fā)送Offer(pc.createOffer)
和遠端響應Answer (remote.createAnswer)
瓶蝴。交換的信息就是sdp
-
sdp
是什么毒返?
SDP (Session Description Protocol)
用于描述多媒體會話,以便進行會話通知舷手、會話邀請和其他形式的多媒體會話啟動拧簸。在啟動多媒體電話會議、IP 語音呼叫男窟、流式視頻或其他會話時盆赤,需要向參與者傳達媒體詳細信息贾富、傳輸?shù)刂泛推渌麜捗枋鲈獢?shù)據(jù)。
- 交換
sdp
信息后牺六,兩邊還必須交換有關網(wǎng)絡連接的信息颤枪,pc.onicecandidate
就是干這個的
ICE candidate
直接翻譯:ice 候選人。這個pc.onicecandidate
方法就說明了兩邊通信是直連還是說要通過 TURN
服務器中繼淑际。這個方法里就能得到公共IP
到這里畏纲,我們就了解了獲取
IP
代碼的意思。拿到了公共IP
春缕,至于內(nèi)網(wǎng)IP
盗胀,瀏覽器做了限制,放開限制才能拿到锄贼, 以下是不同瀏覽器放開限制的方法
火狐(FireFox) 刪除隱藏IP
瀏覽器輸入 about:config
搜索配置 media.peerconnection.enabled 改為false ( 刷新程序,IP正常顯示 )
谷歌(Chrome) 刪除隱藏IP
瀏覽器輸入:chrome://flags/#enable-webrtc-hide-local-ips-with-mdns
把 Anonymize local IPs exposed by WebRTC 設置為 disabled ( 刷新程序,IP正常顯示 )
edge瀏覽器刪除隱藏ip
瀏覽器輸入: edge://flags/#enable-webrtc-hide-local-ips-with-mdns
把 Anonymize local IPs exposed by WebRTC 設置為 disabled ( 刷新程序,IP正常顯示 )
四票灰、 使用設備指紋
首先可以想到的是使用uuid
生成一個放在本地,但是不夠固定咱娶。刪了本地存的米间,在瀏覽器版本未變的情況下就又生成了一個新的。
npm 上的fingerprintjs
這個指紋信息可以是字體膘侮、canvas屈糊、插件、屏幕分辨率琼了、時區(qū)逻锐、地理位置或者是你使用的語言等其他的參數(shù),信息越多并且信息的區(qū)別度越大雕薪,越能決定瀏覽器指紋的準確性昧诱。
在高版本要獲得許可了,可以使用免費的低版本版本所袁。
實測使用它在不同機器上盏档,相同版本瀏覽器下生成唯一id
是不一樣的,似乎可用燥爷。
依然要注意以下問題:
- 升級瀏覽器后蜈亩,
id
會變 (重裝瀏覽器,大概率版本號也變了) - 穩(wěn)定性前翎,這個
id
會持續(xù)多久稚配。文檔提到免費版維持幾周 - 不同的瀏覽器生成的
id
是不一樣的。
這里我在登陸時生成一次后港华,存在本地道川。后續(xù)登陸不再生成,并結(jié)合瀏覽器名稱和版本,作為唯一標識id
冒萄‰叮基本滿足使用場景來判斷這個用戶是否在另一個人的機器上登陸過