如何使用JavaScript获取本地/内部IP地址

13

如何使用WebRTC获取本地客户端IP。

我不需要客户端的REMOTE_ADDR,而是他的本地网络IP。 我曾在像sharedrop.com这样的网站上看到过,它可以使用WebRTC识别同一网络中的计算机。

在PHP中,我使用以下代码获取客户端远程IP:

<?php
  echo $_SERVER["REMOTE_ADDR"]; // which would return 72.72.72.175
?>

我在stackoverflow上搜索了一遍,但每个问题都使用远程地址作为答案。

如何使用JavaScript获取本地IP(例如192.168.1.24),而不是远程地址。


1
@JaromandaX 不幸的是,这是可能的... - mido
1
@mido22 - 这真是让人烦恼 :p - Jaromanda X
Chrome将WebRTC默认更改为mDNS并破坏了内部网络。 - Dominic Cerisano
2个回答

23

更新

不幸的是,下面的答案已经过时了,因为浏览器出于安全考虑已更改了此行为。请参阅此StackOverflow Q&A以获取更多详细信息.


我从哪里获得了代码 --> 源代码

你可以在这里找到演示 --> 演示

我修改了源代码,减少了代码行数,不进行任何stun请求,因为您只需要本地IP而不是公共IP,下面的代码适用于最新版本的Firefox和Chrome:

    window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;   //compatibility for firefox and chrome
    var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};      
    pc.createDataChannel("");    //create a bogus data channel
    pc.createOffer(pc.setLocalDescription.bind(pc), noop);    // create offer and set local description
    pc.onicecandidate = function(ice){  //listen for candidate events
        if(!ice || !ice.candidate || !ice.candidate.candidate)  return;
        var myIP = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
        console.log('my IP: ', myIP);   
        pc.onicecandidate = noop;
    };
    

这里正在发生的是,我们正在创建一个虚假的对等连接,并且为了让远程对等体联系我们,我们通常要互相交换ice candidates。通过读取ice candidates,我们可以知道用户的IP地址。


4
这实际上具有安全隐患,因为这使得攻击者能够找出当前用户的内部IP地址。 - Dinis Cruz
2
这段编程代码缺少清理代码以在使用完成后关闭该连接。反复调用它最终会抛出异常。 - spy
1
Safari怎么样? - Nebi M Aydin
2
Chrome将WebRTC默认更改为mDNS并破坏了内部网络。 - Dominic Cerisano
它对我来说不起作用:未捕获的类型错误:无法读取 null 的属性(读取 '1') - Alexey Sh.

2

您可以在现代浏览器上使用此版本(具有 Promisesasync/await

// minified onliner, 219b
const ip = await new Promise((s,f,c=new RTCPeerConnection(),k='candidate')=>(c.createDataChannel(''),c.createOffer(o=>c.setLocalDescription(o),f),c.onicecandidate=i=>i&&i[k]&&i[k][k]&&c.close(s(i[k][k].split(' ')[4]))))

或者,未经压缩的代码:
// cleaned, 363b
const ip = await new Promise((resolve, reject) => {
  const conn = new RTCPeerConnection()
  conn.createDataChannel('')
  conn.createOffer(offer => conn.setLocalDescription(offer), reject)
  conn.onicecandidate = ice => {
    if (ice && ice.candidate && ice.candidate.candidate) {
      resolve(ice.candidate.candidate.split(' ')[4])
      conn.close()
    }
  }
})

2
Chrome将WebRTC默认更改为mDNS并破坏了内部网络。 - Dominic Cerisano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接