노드에서 사용자의 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

http 및 net 설명서를 참조하십시오

편집하다

@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 Gupta 가 Martin 이 x-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 를 유지 하고 IPv4 및 IPv6을 모두 지원 하는 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.