IT

JavaScript를 통해 사용자 로컬 LAN IP 주소를 얻을 수 있습니까?

lottoking 2020. 9. 11. 08:17
반응형

JavaScript를 통해 사용자 로컬 LAN IP 주소를 얻을 수 있습니까?


이 질문에 대한 초기 반응은 "아니오", "알 수 없습니다", "필요하지 않습니다."뭔가 잘못하고 있습니다. 내가 원하는 것은 사용자 LAN IP 주소를 가져 오는 웹 페이지에 표시하는 것입니다. 왜? 이것이 내가 작업중 인 페이지의 전부이기 때문에 방문자에 대해 가능한 한 많은 정보를 표시합니다. http://www.whatsmyip.org/more-info-about-you/

따라서 정보 제공 목적으로 사용자에게 표시하는 것 외에는 실제로 아무것도하지 않습니다. 저는 작은 Java 애플릿을 사용 하여이 작업을 수행했습니다. 꽤 잘 작동했습니다. 그러나 요즘 브라우저는 당신이 동의하고 신뢰를 많이해서 아주 사소한 자바 애플릿도 실행하기 때문에 나는 전혀 실행하지 않을 것입니다.

그래서 잠시 동안이 기능을 제거했지만 가능하면 되돌리고 싶습니다. 제가 컴퓨터 컨설턴트로서 사용하는 것이 었습니다. 이 웹 사이트로 이동하여 네트워크가 실행중인 IP 범위를 확인하는 것이 시스템 환경 설정, 그리고 활성화 된 인터페이스로 이동하는 것보다 빠 사용하지 않습니다.

그래서 나는 자바만으로 할 수있는 방법이 있는지 궁금합니다. 자바 확장가 브라우저에 존재하는 위치가 어디에 있고 있고, 설치 가능한 방식으로 액세스 할 수있는 새로운 개체가 있습니다. 클라이언트 중 어느 것입니까? 대체면 완전히 다른 방법이 있습니까? 내가 생각할 수있는 유일한 방법은 자바 애플릿 또는 플래시 객체입니다. 차라리 그 중 하나를하지 않을 것입니다.


결과적으로 HTML5의 최신 WebRTC 확장은 자바 펼쳐가 로컬 클라이언트 IP 주소를 쿼리 할 수 ​​있도록합니다. 개념 증명은 http://net.ipcalf.com에서 확인할 수 있습니다.

이 기능은 바람직하지 않습니다 . 그러나 논란의 여지가있는 성격을 감안할 때 나는이 행동에 의존하는 것에 대해 신중할 것입니다. 그럼에도 불구하고 귀하의 의도 된 목적을 완벽하고 이해하고 해결 생각합니다 (사용자에게 브라우저에서 유출되는 내용을 공개).


afourney의 답변 외에도이 코드는 WebRTC (Chrome 및 Firefox)를 지원하는 브라우저에서 작동합니다. 사이트가 IP (사용자의 위치 또는 사용자 미디어의 경우)를 요청하도록 기능을 구현하려는 움직임이 들었습니다. 아직 두 브라우저 중 하나에서 구현되지 않습니다.

다음은 소스 코드 의 수정 된 버전으로 , 공개 IP가 아닌 로컬 IP 만 지원 줄을 줄이면서 스턴 요청을하지 않습니다.

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)
{
 if (ice && ice.candidate && ice.candidate.candidate)
 {
  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;
 }
};

원격 피어가 당사에 연락 할 수있는 더미 피어 연결을 생성하고 있습니다. 우리는 일반적으로 얼음 후보를 서로 교환하고 얼음 후보를 읽고 사용자의 IP를 알 수 있습니다.

>-당신은 견본을 사용하여 데모를 수행 할 수 있습니다 .


나는 미도의 포스트를 정리하고 기능을 정리했다. 이것은 false또는 array. 테스트 할 때 웹 개발자 콘솔에서 배열을 축소해야 점을 기억하십시오. 장식 할 수있는 것입니다 기본 동작으로 인해 빈을 반환합니다 속일 수 있습니다 array.

function ip_local()
{
 var ip = false;
 window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || false;

 if (window.RTCPeerConnection)
 {
  ip = [];
  var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};
  pc.createDataChannel('');
  pc.createOffer(pc.setLocalDescription.bind(pc), noop);

  pc.onicecandidate = function(event)
  {
   if (event && event.candidate && event.candidate.candidate)
   {
    var s = event.candidate.candidate.split('\n');
    ip.push(s[0].split(' ')[4]);
   }
  }
 }

 return ip;
}

또한 IE11 및 이전 버전에서 border-radius완전히 지원 되지 않는 비트 중 하나이지만 CSS와 같이 구식이 아니라는 점을 기억하십시오 . 항상 객체 감지를 사용하고, 상당히 오래된 브라우저 (예 : Firefox 4, IE9, Opera 12.1)에서 테스트하고 최신 스크립트가 최신 코드를 깨뜨리지 않는지 확인하십시오. 또한 항상 표준 준수 코드를 먼저 감지 하므로 CSS 접두사가 표준 비 접두어 코드를 먼저 감지 한 다음 장기 지원이 결국 나머지 존재에 대해 표준화 될 것이므로 대체합니다.


한 WebRTC API는 클라이언트의 로컬 IP를 검색 할 수 있습니다.

그러나 브라우저가이를 지원하지 않거나 클라이언트가 보안상의 이유로 비활성화했을 수 있습니다. 어쨌든 미래에 패치 될 가능성이 있기 때문에 장기적 으로이 "해킹"에 의존해서는 안됩니다 (Cullen Fluffy Jennings의 답변 참조).

아래의 ECMAScript 6 코드는이를 수행하는 방법을 보여줍니다.

/* ES6 */
const findLocalIp = (logInfo = true) => new Promise( (resolve, reject) => {
    window.RTCPeerConnection = window.RTCPeerConnection 
                            || window.mozRTCPeerConnection 
                            || window.webkitRTCPeerConnection;

    if ( typeof window.RTCPeerConnection == 'undefined' )
        return reject('WebRTC not supported by browser');

    let pc = new RTCPeerConnection();
    let ips = [];

    pc.createDataChannel("");
    pc.createOffer()
     .then(offer => pc.setLocalDescription(offer))
     .catch(err => reject(err));
    pc.onicecandidate = event => {
        if ( !event || !event.candidate ) {
            // All ICE candidates have been sent.
            if ( ips.length == 0 )
                return reject('WebRTC disabled or restricted by browser');

            return resolve(ips);
        }

        let parts = event.candidate.candidate.split(' ');
        let [base,componentId,protocol,priority,ip,port,,type,...attr] = parts;
        let component = ['rtp', 'rtpc'];

        if ( ! ips.some(e => e == ip) )
            ips.push(ip);

        if ( ! logInfo )
            return;

        console.log(" candidate: " + base.split(':')[1]);
        console.log(" component: " + component[componentId - 1]);
        console.log("  protocol: " + protocol);
        console.log("  priority: " + priority);
        console.log("        ip: " + ip);
        console.log("      port: " + port);
        console.log("      type: " + type);

        if ( attr.length ) {
            console.log("attributes: ");
            for(let i = 0; i < attr.length; i += 2)
                console.log("> " + attr[i] + ": " + attr[i+1]);
        }

        console.log();
    };
} );

내가 글을 return resolve(..)쓰거나 return reject(..)단축키로 사용하는 것에 주목하십시오 . 두 함수 모두 아무것도 반환하지 않습니다.

그러면 다음과 같은 것이있을 수 있습니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Local IP</title>
</head>
<body>
    <h1>My local IP is</h1>
    <p id="ip">Loading..</p>
    <script src="ip.js"></script>
    <script>
    let p = document.getElementById('ip');
    findLocalIp().then(
        ips => {
            let s = '';
            ips.forEach( ip => s += ip + '<br>' );
            p.innerHTML = s;
        },
        err => p.innerHTML = err
    );
    </script>
</body>
</html>

function getUserIP(onNewIP) { //  onNewIp - your listener function for new IPs
  //compatibility for firefox and chrome
  var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
  var pc = new myPeerConnection({
      iceServers: []
    }),
    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 iterateIP(ip) {
    if (!localIPs[ip]) onNewIP(ip);
    localIPs[ip] = true;
  }
  onNewIP
  //create a bogus data channel
  pc.createDataChannel("");

  // create offer and set local description
  pc.createOffer().then(function(sdp) {
    sdp.sdp.split('\n').forEach(function(line) {
      if (line.indexOf('candidate') < 0) return;
      line.match(ipRegex).forEach(iterateIP);
    });

    pc.setLocalDescription(sdp, noop, noop);
  }).catch(function(reason) {
    // An error occurred, so handle the failure to connect
  });

  //listen for candidate events
  pc.onicecandidate = function(ice) {
    if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
    ice.candidate.candidate.match(ipRegex).forEach(iterateIP);
  };
}
getUserIP(console.log)


이 문제를 완화하기 위해 브라우저가 추가 할 수있는 제한 사항과 IETF에서 수행하는 작업 및 IP 처리에 대한 IETF SPEC 에서 이것이 필요한 이유에 대한 자세한 정보를 찾을 수 있습니다.

참고 URL : https://stackoverflow.com/questions/20194722/can-you-get-a-users-local-lan-ip-address-via-javascript

반응형