[node.js] Express.js req.ip가 :: ffff : 127.0.0.1을 반환합니다.

현재 요청한 사용자의 IP를 얻으려고합니다. 문제는 IP가 ::ffff:127.0.0.1대신 반환된다는 것입니다 127.0.0.1. 나는 trusted proxy옵션을 사용하려고 시도했지만 (프록시를 사용하지 않지만) req.ips비어 있습니다. 4.x Express.js 사용.

router.get('/', function(req, res, next) {
    console.log('ip', req.ip)
    res.send({})
});



답변

::ffff:IPv6 (128 비트) 공간 내에 배치되는 IPv4 (32 비트) 주소의 서브넷 접두사입니다. IPv6는 서브넷 접두사와 인터페이스 접미사의 두 부분으로 나뉩니다. 각각의 길이는 64 비트 또는 4 개의 16 진수 문자로 구성된 4 개의 그룹입니다.

IPv6를, 당신은 의미가 연속 0을 앞에 0을 제거하고 제거 할 수 있습니다 ::ffff:사실로 변환 0000:0000:ffff:0000어떤 IPv6의 프로세서는 IPv4 주소와 함께 일하고 이해하고 처리 할 수 있도록이 주소는 IPv6를 서브넷 접두사는 IPv4로 지정되어 있습니다, 따라서.

가까운 장래에 IP 주소는 모두 IPv6이 될 것입니다. 이는 IPv4 주소 공간에서 거의 숫자가 부족하기 때문입니다 (42 억, 기타 목적을위한 공간 제외).

IPv6는 훨씬 더 큰 공간을 허용합니다. “누구에게나 340 억 달러면 충분해야합니다”-Bill Gates가 IPv6에 대해 이야기합니다.

IPv6 네임 스페이스를 사용하여 IP 주소 주소 지정을 시작하는 것이 중요하므로 ::ffff:나중에 해당 콜론 사이에 실제 16 진수 데이터가있을 것이므로 코드에를 포함 해야합니다. 미적 이유로 제거하면 IPv6 네트워크로 전환하거나 IPv6 주소와 마주 칠 때 코드가 손상됩니다.

일부 네트워크는 현재 IPv6를 실행하고 있으며 곧 IPv6 IP 주소에 직면하게 될 것입니다. 지금 도약하지 않으면 나중에 코드가 깨질 위험이 있습니다.

문제의 TL; DR (짧은) 버전은 다음과 같습니다. 모든 것이 잘 작동합니다. 변경하지 마십시오. IPv4 주소의 IPv6 버전입니다.

IPv4
IPv6

코드가 IPv6과 호환되도록하려면 ::ffff:접두사를 확인하기 만하면됩니다 … 존재하는 경우 제거하고 나머지를 IPv4로 처리합니다 … ::ffff:존재하지 않는 경우 IPv6 주소이고 처리해야합니다. 문자열에 마침표가 있는지 확인하여 다시 확인할 수 있습니다. 그렇다면 IPv4입니다.

IP 주소에 대한 조정을 제외하고 모든 것을 염두에 두십시오. IP를 기록하는 것입니다. 이는 파서 및 로그 집계에 중요 할 ::ffff:127.0.0.1것입니다. IP를 변경할 필요가 없다면받은 그대로 두십시오.


답변

이것은 ipv6의 특징 인 것 같습니다. ipv4 주소의 경우 ipv6은 ipv6 표기법과 ipv4 표기법을 혼합 한 것 같습니다.

단순하고 혼합되지 않은 표기법으로 ipv4 및 ipv6 주소를 모두 얻으려면 다음을 사용합니다.

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if (ip.substr(0, 7) == "::ffff:") {
  ip = ip.substr(7)
}


답변

IPv4 만 필요한 경우 노드 서버가 IPv4를 사용하여 수신하도록 할 수 있습니다.

빠른 앱 편집의 경우 /bin/www:

변화

server.listen(port);

server.listen(port, '0.0.0.0');

이것은 적어도 나를 위해 일했습니다.

https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback


답변

Windows 7에는 기본적으로 IPv6이 활성화되어 있습니다. 내 서버가 IPv4에서만 수신하지만 Windows 7은 ::ffff:IPv6 로의 전환의 일부로 접두사를 IPv4로 보냅니다.

::ffff:0:0:0/96 — SIIT (Stateless IP / ICMP Translation) 프로토콜에서 사용하는 IPv4 변환 주소에 사용되는 접두사입니다.

IPv4에서 전환


답변

ipv4 매핑 된 주소를 비교하는 데 문제가 있었고 ipaddr.js 라이브러리가 도움이되는 것을 발견했습니다. 🙂

예 :

_.isEqual(ipaddr.process('::ffff:127.0.0.1'), ipaddr.process('127.0.0.1')) === true


답변

서브넷을 제거하여 정확한 IP 주소를 얻으려면 이것을 시도하십시오.

    let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    ip = ip.toString().replace('::ffff:', '');


답변

소켓을 사용하여 Ip 주소를 단독으로 또는 지정된 제품군으로 가져올 수 있습니다.

     var app = require('express')();

 app.get("/ip", (req, res) => {
        console.log(req.ip) 
       let ip = req.ip.split(':');
        let ip_details = req.socket.address();
          console.log(ip_details);                     
   // { address: '::ffff:127.0.0.1', family: 'IPv6', port: 3001 

           console.log(ip[3]);//127.0.0.1
                            res.json(ip[3]);  
      }