[node.js] Express.js : 원격 클라이언트 주소를 얻는 방법

원격 사용자 IP 주소를 얻는 방법을 완전히 이해하지 못합니다.

다음과 같은 간단한 요청 경로가 있다고 가정 해 보겠습니다.

app.get(/, function (req, res){
   var forwardedIpsStr = req.header('x-forwarded-for');
   var IP = '';

   if (forwardedIpsStr) {
      IP = forwardedIps = forwardedIpsStr.split(',')[0];
   }
});

실제 사용자의 IP 주소를 얻기 위해 위의 방법이 올바른가요? 아니면 더 나은 방법이 있습니까? 프록시는 어떻습니까?



답변

NGiNX와 같은 프록시 뒤에서 실행 중이거나 가지고있는 것이 있다면 ‘x-forwarded-for’를 확인해야합니다.

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

프록시가 ‘귀하의 것’이 아닌 경우 ‘x-forwarded-for’헤더를 스푸핑 할 수 있기 때문에 신뢰하지 않습니다.


답변

@alessioalex의 답변이 효과가 있지만 Express-guide프록시 뒤에 표현 섹션에 명시된 다른 방법이 있습니다.

  1. app.set('trust proxy', true)빠른 초기화 코드에 추가하십시오 .
  2. 원격 클라이언트의 IP를 얻으려면 req.ip또는 req.ips일반적인 방법으로 사용하십시오 (역 프록시가없는 것처럼)

선택적인 독서 :

  • req.ip또는을 사용하십시오 req.ips. req.connection.remoteAddress이 솔루션에서는 작동하지 않습니다.
  • 헤더로 'trust proxy'전달 된 모든 것을 신뢰하는 것보다 더 정교한 것을 필요로하는 경우 더 많은 옵션을 사용할 수 있습니다 x-forwarded-for(예 : 프록시가 신뢰할 수없는 소스에서 기존 x-forwarded-for 헤더를 제거하지 않는 경우). 자세한 내용은 링크 된 가이드를 참조하십시오.
  • 프록시 서버가 x-forwarded-for헤더를 채우지 않으면 두 가지 가능성이 있습니다.
    1. 프록시 서버는 원래 요청 위치에 대한 정보를 릴레이하지 않습니다. 이 경우 요청의 원래 위치를 알 수있는 방법이 없습니다. 먼저 프록시 서버의 구성을 수정해야합니다.
      • 예를 들어, nginx를 리버스 프록시로 사용하는 경우 proxy_set_header X-Forwarded-For $remote_addr;구성 에 추가 해야합니다.
    2. 프록시 서버는 요청이 원래 있던 위치에 대한 정보 (예 : 사용자 정의 http 헤더)를 릴레이합니다. 이 경우이 답변이 작동하지 않습니다. 해당 정보를 가져 오는 사용자 정의 방법이있을 수 있지만 먼저 메커니즘을 이해해야합니다.

답변

에서 nginx.conf파일 :
proxy_set_header X-Real-IP $remote_addr;

에서 node.js서버 파일 :
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;

소문자 헤더를 표현합니다.


답변

특히 노드의 경우 이벤트 연결 에서 http 서버 구성 요소에 대한 설명서 는 다음 같이 말합니다.

새 TCP 스트림이 설정되면 [트리거 됨]. [The] socket은 net.Socket 유형의 객체입니다. 일반적으로 사용자는이 이벤트에 액세스하고 싶지 않습니다. 특히, 소켓은 프로토콜 파서가 소켓에 연결하는 방식 때문에 읽을 수있는 이벤트를 생성하지 않습니다. 소켓은에서 액세스 할 수도 있습니다 request.connection.

따라서 request.connection이는 소켓 임을 의미 하며 설명서 에 따르면 문서에 따라 socket.remoteAddress 속성이 있습니다.

원격 IP 주소의 문자열 표현 예를 들어, ’74 .125.127.100 ‘또는’2001 : 4860 : a005 :: 68 ‘입니다.

명시 적으로 요청 객체는 Node http 요청 객체의 인스턴스이기도 하므로이 방법은 여전히 ​​작동합니다.

그러나 Express.js에서는 요청에 req.ipreq.ips 라는 두 가지 속성이 이미 있습니다.

req.ip

원격 주소를 반환하거나 “신뢰 프록시”가 활성화 된 경우 업스트림 주소를 반환합니다.

req.ips

“신뢰 프록시는” 이다 true는 “X가 전달 된-은”IP 주소 목록을 구문 분석하고 배열, 그렇지 않은 경우는 하늘의 배열이 반환을 반환합니다. 예를 들어 값이 “client, proxy1, proxy2″인 경우 배열 “”client “,”proxy1 “,”proxy2 “]를 수신합니다. 여기서”proxy2 “는 가장 다운 스트림입니다.

그것은 가치가 언급 될 수있다, 내 이해에 따르면, Express는 req.ip보다 더 나은 접근 방식 req.connection.remoteAddress때문에,req.ip 실제 클라이언트 ip (신뢰할 수있는 프록시가 명시 적으로 활성화되어있는 경우)를 포함하고 다른 하나는 프록시의 IP 주소를 포함 할 수 가 있습니다. 하나).

이것이 현재 받아 들여진 대답이 제안하는 이유입니다.

var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress;

req.headers['x-forwarded-for']표현에 해당 될 것입니다 req.ip.


답변

  1. 더하다 app.set('trust proxy', true)
  2. 사용 req.ip또는 req.ips일반적인 방법으로

답변

이것은 이 답변에 대한 추가 정보 일뿐 입니다.

당신이 사용하는 경우 nginxproxy_set_header X-Real-IP $remote_addr; 사이트의 위치 블록에 추가 합니다. /etc/nginx/sites-available/www.example.com예를 들어. 다음은 예제 서버 블록입니다.

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_pass http://127.0.1.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

다시 시작한 후에 nginxnode/ express응용 프로그램 경로 에서 IP에 액세스 할 수 있습니다.req.headers['x-real-ip'] || req.connection.remoteAddress;


답변

에 따르면 프록시 뒤에 익스프레스 , req.ip사용자가 설정 한 경우 계정 역방향 프록시에 취한 trust proxy제대로. 따라서 req.connection.remoteAddress네트워크 계층에서 얻거나 프록시를 인식하지 못하는 것보다 낫습니다 .