Você pode obter um endereço IP local da LAN dos usuários via JavaScript?

Sei que a reação inicial a essa pergunta é “não” e “não pode ser feito” e “você não deveria precisar, está fazendo algo errado”. O que estou tentando fazer é obter o endereço IP da LAN dos usuários e exibi-lo na página da web. Por quê? Porque é sobre isso que a página em que estou trabalhando mostra o máximo de informações possível sobre você, o visitante: http://www.whatsmyip.org/more-info-about-you/

Então, na verdade, não estou fazendo nada com o IP, além de mostrá-lo ao usuário para fins informativos. Eu costumava fazer isso usando um pequeno applet Java. Funcionou muito bem. Mas hoje em dia, o navegador faz com que você acerte e confie tantas vezes, para executar até o menor miniaplicativo java, que prefiro não executar nenhum.

Então, por um tempo, acabei de me livrar desse recurso, mas gostaria de voltar, se possível. Era algo que eu, como consultor de informática, usava de vez em quando. É mais rápido acessar esse site para ver em qual faixa de IP uma rede está sendo executada, do que entrar em Preferências do Sistema, Rede e, em seguida, qualquer interface que esteja ativa.

Então, eu estou pensando, esperando, se há alguma maneira de fazê-lo em javascript sozinho? Talvez algum novo object que você possa acessar, semelhante à maneira como o javascript pode perguntar ao navegador onde está a localização geográfica na Terra. Talvez haja algo semelhante para informações de redes de clientes? Se não, talvez haja alguma outra maneira de fazê-lo? As únicas maneiras em que consigo pensar são um applet java ou um object flash. Eu prefiro não fazer nenhum desses.

Como se constata, a recente extensão WebRTC do HTML5 permite que o javascript consulte o endereço IP do cliente local. Uma prova de conceito está disponível aqui: http://net.ipcalf.com

Esse recurso é aparentemente por design e não é um bug. No entanto, dada a sua natureza controversa, eu seria cauteloso sobre confiar neste comportamento. No entanto, acho que ele atende perfeitamente e adequadamente a sua finalidade (revelando ao usuário o que o navegador está vazando).

Além da resposta da fourney, este código funciona em navegadores que suportam WebRTC (Chrome e Firefox). Ouvi dizer que há um movimento em andamento para implementar um recurso que faz os sites solicitarem o IP (como no caso de localização geográfica ou mídia do usuário), embora ele ainda precise ser implementado em qualquer um desses navegadores.

Aqui está uma versão modificada do código-fonte , reduziu as linhas, não fazendo nenhuma solicitação de atordoamento, pois você só quer o IP local e não o IP público:

 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; } }; 

Estamos criando uma conexão simulada para o peer remoto nos contatar. Geralmente trocamos candidatos de gelo uns com os outros e lendo os candidatos de gelo podemos dizer o ip do usuário.

Você pode encontrar uma demonstração em -> Demo

 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; } //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); }; } 

Eu limpei o post do mido e limpei a function que eles encontraram. Isso retornará false ou uma array . Ao testar, lembre-se de que é necessário reduzir o array no console do desenvolvedor da Web. Caso contrário, o comportamento padrão não intuitivo pode levá-lo a pensar que está retornando um array vazio.

 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; } 

Além disso, lembre-se de que isso não é algo antigo como o border-radius CSS border-radius embora um desses bits não seja suportado pelo IE11 ou mais antigo. Sempre use detecção de objects, teste em navegadores razoavelmente mais antigos (por exemplo, Firefox 4, IE9, Opera 12.1) e certifique-se de que seus scripts mais novos não estejam quebrando seus novos trechos de código. Além disso, sempre detecte primeiro o código em conformidade com os padrões, portanto, se houver algo com um prefixo CSS detecte primeiro o código padrão não prefixado e depois recue como no suporte de longo prazo, ele será padronizado para o restante de sua existência.

Você pode encontrar mais informações sobre quais limitações os navegadores provavelmente adicionarão para atenuar isso e o que a IETF está fazendo sobre isso, bem como por que isso é necessário no IETF SPEC sobre o tratamento de IP