노드에서 사용자의 IP 주소를 확인하는 방법


349

컨트롤러 내에서 주어진 요청의 IP 주소를 어떻게 확인할 수 있습니까? 예를 들어 (명시 적으로) :

app.post('/get/ip/address', function (req, res) {
    // need access to IP address here
})

22
당신은 Express를 사용하는 경우 사용할 수 있습니다 req.ip - 소스 expressjs.com/en/api.html#req.ip
FrickeFresh

이것을보십시오 : github.com/indutny/node-ip
Stephen Last

16
localhost내가했던 것처럼 일하는 사람들에게는 아래의 모든 답변 (거의 모든 답변이 거의 작동하지 않음)의 결과가 올 수 있습니다 ::1. 이것은 언젠가 혼란스러워했습니다. 나중에 ::1실제 IP 주소이며 IPV6localhost에 대한 표기법 이라는 것을 알았습니다 . Hope this helps someone
Pramesh Bajracharya

답변:


452

당신의에서 request객체라는 속성이 connectionA는, net.Socket객체. net.Socket 객체에는 속성이 있으므로이 remoteAddress호출로 IP를 얻을 수 있어야합니다.

request.connection.remoteAddress

httpnet 설명서를 참조하십시오

편집하다

@juand가 주석에서 지적했듯이 서버가 프록시 뒤에있는 경우 원격 IP를 얻는 올바른 방법은 다음과 같습니다. request.headers['x-forwarded-for']


6
이것은 whatismyip.com이 제공하는 것과 다른 IP 주소를 제공합니다. 왜 그런가요?
샤문

3
API 서비스를 no.de 인스턴스 에 설치했습니다 . 내 컴퓨터에서 액세스하려고하면 IP 주소가 "10.2.XXX.YYY"인 반면 실제 IP는 "67.250.AAA.BBB"
Shamoon

7
request.headers [ 'X-Forwarded-For']
0x6A75616E

4
net.Stream은 이제 net.Socket이며 설명서는 여기에 있습니다. nodejs.org/api/net.html#net_class_net_socket
monsur

4
Heroku에게 관심이있는 사람이라면 : request.headers['x-forwarded-for']
FueledPublishing

407
var ip = req.headers['x-forwarded-for'] || 
     req.connection.remoteAddress || 
     req.socket.remoteAddress ||
     (req.connection.socket ? req.connection.socket.remoteAddress : null);

에서에 하나 이상의 IP 주소를 얻을 수 있습니다 req.headers['x-forwarded-for']. 또한x-forwarded-for 오류가 발생할 수 헤더가 항상 설정되지는 않습니다.

필드의 일반적인 형식은 다음과 같습니다.

x 전달 : client, proxy1, proxy2, proxy3

여기서 값은 쉼표 + 공백으로 구분 된 IP 주소 목록이며, 가장 왼쪽은 원래 클라이언트이며 요청을받은 각 연속 프록시는 요청을받은 IP 주소를 추가합니다. 이 예에서 요청은 proxy1,proxy2 다음 proxy3. proxy3요청의 원격 주소로 나타납니다.

이것은 Arnav GuptaMartinx-forwarded-for설정하지 않은 경우에 대한 주석에서 제안한 수정 사항으로 제안한 솔루션 입니다.

var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || 
         req.connection.remoteAddress || 
         req.socket.remoteAddress || 
         req.connection.socket.remoteAddress

9
그래도 이러한 헤더의 스푸핑을 방지하는 방법은 무엇입니까?
Domi

8
이것은 일반적으로 잘 작동하지만 어떤 이유로 최근에 "정의되지 않은 'remoteAddress'속성을 읽을 수 없습니다"라는 오류가 발생했습니다 req.connection.socket. 왜 / 어떤 조건으로 인해 발생하는지 확실하지 않지만 req.connection.socket이것이 발생하면 서버 충돌을 피하기 위해 존재 하는지 확인하는 것이 좋습니다 .
Matt Browne

9
마지막 줄 req.connection.socket.remoteAddress 던지는 오류. 조심하십시오.
yAnTar

11
반환 된 IP 주소는 :: 1입니다. 왜?
Bagusflyer

3
pop () 작동 방식을 살펴보면 원하는 프록시가 아닌 마지막 프록시를 얻는 것처럼 보입니다. 내가 잘못?
Michel


31

DRY 를 유지 하고 IPv4IPv6을 모두 지원 하는 node-ipware 만 사용할 수 있습니다 .

설치:

npm install ipware

app.js 또는 미들웨어에서 :

var getIP = require('ipware')().get_ip;
app.use(function(req, res, next) {
    var ipInfo = getIP(req);
    console.log(ipInfo);
    // { clientIp: '127.0.0.1', clientIpRoutable: false }
    next();
});

사용자의 IP 주소를 얻으려고 최선을 다하거나 사용자의 IP 주소를 127.0.0.1확인할 수 없음을 표시하기 위해 돌아갑니다 . README 파일에서 고급 옵션을 살펴보십시오 .


40
"또는 사용자의 IP 주소를 확인할 수 없음을 나타 내기 위해 127.0.0.1을 반환합니다."127.0.0.1과 알 수 없음 사이에는 큰 차이가 있습니다.
Nepoxx

4
:ffff:(not my IP address)Heroku에서 테스트 할 때 이상한 것을 반환했습니다 . @ edmar-miyake의 답변이 제대로 작동합니다.
Nilloc

'x-forwarded-for'경우 right2left 조회를 사용한다면 IP가 어떻게 될지 궁금합니다. var ip_info = get_ip (req, right_most_proxy = True), 일부 설정에서와 같이 클라이언트 IP가 가장 적합한 IP 일 수 있습니다.
un33k

2
그 방법은 clientIp: '::1'저를 위해 돌아오고 있습니다. 작동하지 않는 것 같습니다.
JamEngulfer

@JamEngulfer-ipware는 request.headers []를 통해 ip 주소가 앱으로 올바르게 전달 된 경우에만 작동합니다. 예 : AWS LBS는 Ix 주소를 'x-forwarded-for'로 보내고 커스텀 NginX는 다른 변수를 사용합니다. ipware는 IP 주소를 알아 내기 위해 최선의 시도를하지만 IP가 헤더에 전달 된 경우에만 가능합니다.
un33k

19

request-ip를 사용 하여 사용자의 IP 주소를 검색 할 수 있습니다 . 그것은 여러 가지 다른 경우를 처리하며, 그중 일부는 다른 답변에서 언급됩니다.

공개 :이 모듈을 만들었습니다

설치:

npm install request-ip

앱에서 :

var requestIp = require('request-ip');

// inside middleware handler
var ipMiddleware = function(req, res, next) {
    var clientIp = requestIp.getClientIp(req); // on localhost > 127.0.0.1
    next();
};

도움이 되었기를 바랍니다


2
github.com/pbojinov/request-ip/blob/master/index.js 에서 패키지 request-ip의 소스 코드를 확인하여 x-forwarded-for 및 모든 종류의 다른 헤더를 확인하여 AWS ELB, Cloudflare와 같은 인기있는로드 밸런서가 있는지 확인합니다. , Akamai, nginx, Rackspace LB 및 Riverbed 's Stingray
Giorgio

1
그것은 null나를 위해 돌아옵니다 .
S.M_Emamian 2016 년

같은 것이 대신 사용됩니다request.headers['x-forwarded-for']
Prathamesh More

19

request.headers['x-forwarded-for'] || request.connection.remoteAddress

경우 x-forwarded-for헤더가 그 다음을 사용하고, 그렇지 않으면를 사용.remoteAddress 속성을.

x-forwarded-for헤더에 설정 부하 분산 (또는 프록시 다른 유형)를 통과 요청에 추가 HTTP 또는 HTTPS (그것은에서 균형 때 요청에이 헤더를 추가 할 수도 있습니다 TCP의 사용 수준 프록시 프로토콜 ). request.connection.remoteAddress속성에 클라이언트의 퍼블릭 IP 주소가 아닌로드 밸런서의 프라이빗 IP 주소가 포함 되기 때문 입니다. 위의 순서대로 OR 문 을 사용하여 x-forwarded-for헤더 의 존재를 확인하고 존재 하는 경우이를 사용하십시오 request.connection.remoteAddress.


12

다음 기능은 모든 경우에 적용됩니다.

var ip;
if (req.headers['x-forwarded-for']) {
    ip = req.headers['x-forwarded-for'].split(",")[0];
} else if (req.connection && req.connection.remoteAddress) {
    ip = req.connection.remoteAddress;
} else {
    ip = req.ip;
}console.log("client IP is *********************" + ip);

ips는 , 저 사이에 있습니다.
ThomasReggi

8

IP 주소를 얻는 방법에는 두 가지가 있습니다.

  1. let ip = req.ip

  2. let ip = req.connection.remoteAddress;

그러나 위의 접근법에는 문제가 있습니다.

Nginx 또는 프록시 뒤에서 앱을 실행하는 경우 모든 단일 IP 주소는 127.0.0.1 .

따라서 사용자의 IP 주소를 얻는 가장 좋은 해결책은 다음과 같습니다.

let ip = req.header('x-forwarded-for') || req.connection.remoteAddress;


6

function getCallerIP(request) {
    var ip = request.headers['x-forwarded-for'] ||
        request.connection.remoteAddress ||
        request.socket.remoteAddress ||
        request.connection.socket.remoteAddress;
    ip = ip.split(',')[0];
    ip = ip.split(':').slice(-1); //in case the ip returned in a format: "::ffff:146.xxx.xxx.xxx"
    return ip;
}


1
ip를 문자열로 사용하려면 마지막 줄을 다음과 같이 바꿀 수 있습니다. ip = ip.split ( ':'). slice (-1) [0]
Ahmad Agbaryah

코드 전용 답변은 권장하지 않습니다. 이 답변이 더 오래되고, 더 잘 설명되어 있고 (많은) 더 많이 찬성 된 답변 보다 어떻게 더 나은지 설명 할 수 있습니까 ?
Dan Dascalescu

5

경고:

중요한 속도 제한을 위해 이것을 맹목적으로 사용하지 마십시오.

let ip = request.headers['x-forwarded-for'].split(',')[0];

스푸핑하는 것은 매우 쉽습니다.

curl --header "X-Forwarded-For: 1.2.3.4" "https://example.com"

이 경우 사용자의 실제 IP 주소는 다음과 같습니다.

let ip = request.headers['x-forwarded-for'].split(',')[1];

다른 답변이 이것을 언급하지 않은 것에 놀랐습니다.


상단의 대답은 이것을 어떻게 처리합니까 pop()될 수 인덱스 1에있는 요소를 점점 더 일반적이다 배열에서 보내고 속지 에 의해 curl --header "X-Forwarded-For: 1.2.3.4, 5.6.7.8" "https://example.com".
Dan Dascalescu

3

여러 개의 IP를 얻는다면 나에게 효과적입니다.

var ipaddress = (req.headers['x-forwarded-for'] || 
req.connection.remoteAddress || 
req.socket.remoteAddress || 
req.connection.socket.remoteAddress).split(",")[0];


3

nodejs에서 간단한 원격 IP 가져 오기 :

var ip = req.header('x-forwarded-for') || req.connection.remoteAddress;

3

nginx 뒤의 노드 10.14에서 다음과 같이 nginx 헤더를 통해 요청하여 ip를 검색 할 수 있습니다.

proxy_set_header X-Real-IP $remote_addr;

그런 다음 app.js에서 :

app.set('trust proxy', true);

그런 다음 원하는 곳에 표시하십시오.

var userIp = req.header('X-Real-IP') || req.connection.remoteAddress;

2

나는 이것이 죽음에 대한 답을 얻었음을 알고 있지만, 여기에 필자가 에어 비앤비 기반 에스 린트 표준을 따르는 현대 ES6 버전이있다.

const getIpAddressFromRequest = (request) => {
  let ipAddr = request.connection.remoteAddress;

  if (request.headers && request.headers['x-forwarded-for']) {
    [ipAddr] = request.headers['x-forwarded-for'].split(',');
  }

  return ipAddr;
};

X-Forwarded-For 헤더는 쉼표로 구분 된 프록시 IP 목록을 포함 할 수 있습니다. 순서는 client, proxy1, proxy2, ..., proxyN입니다. 실제로 사람들은이 헤더에 원하는 것을 제공 할 수있는 프록시를 구현합니다. 로드 밸런서 또는 그 뒤에있는 경우 목록의 첫 번째 IP는 적어도 일부 요청이 통과 한 프록시는 무엇이든 신뢰할 수 있습니다.


1

Graphql-Yoga를 사용하는 경우 다음 기능을 사용할 수 있습니다.

const getRequestIpAddress = (request) => {
    const requestIpAddress = request.request.headers['X-Forwarded-For'] || request.request.connection.remoteAddress
    if (!requestIpAddress) return null

    const ipv4 = new RegExp("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")

    const [ipAddress] = requestIpAddress.match(ipv4)

    return ipAddress
}


-7

같은 문제가 있었지만 자바 스크립트에서도 새로운 것이었지만 req.connection.remoteAddress 로이 문제를 해결했습니다. 그것은 나에게 IP 주소 (그러나 ipv6 형식 :: ffff.192.168.0.101)와 .slice 를 제공하여 7 번째 숫자를 제거했습니다.

var ip = req.connection.remoteAddress;

if (ip.length < 15) 
{   
   ip = ip;
}
else
{
   var nyIP = ip.slice(7);
   ip = nyIP;
}

ipv6는 7 자리 + IPv4가 아니라 완전히 다를 수 있으므로 이것은 좋은 방법이 아닙니다.
Radek

당신이 주소의 시작을 확인하는 경우 @Radek, 그것은 사양을 준수합니다 ( en.wikipedia.org/wiki/IPv6_address의 "IPv4지도"에 대한 CTRL-F 검색) ip= (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined))은 IF ... 위의 코드에서 대체 할 것이다
동기화

나는 개인적으로 npm request-ip에서 getClientIp ()를 감싸서 function getClientIp4(req){ var ip=typeof req==='string'?req:getClientIp(req); return (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined)); }이전에 가져온 ip 또는 요청 객체를 입력으로 받아 ip로 또는 정의되지 않은 결과를 생성합니다
동기화되지 않은
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.