programing

Express.js: 원격 클라이언트 주소를 가져오는 방법

subpage 2023. 5. 14. 10:41
반응형

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.socket.remoteAddress 

프록시가 '당신의 것'이 아니라면, 저는 그것을 믿지 않을 것입니다.'x-forwarded-for'헤더. 스푸핑될 수 있기 때문입니다.

@alessioalex의 답변은 효과가 있지만 Express - 안내서의 Express backdown proxies 섹션에 명시된 다른 방법이 있습니다.

  1. 더하다app.set('trust proxy', true)빠른 초기화 코드로 이동합니다.
  2. 클라이언트의 할 주소를 사용합니다.req.ip또는req.ips일반적인 방식으로(역방향 프록시가 없는 것처럼)

선택적 판독값:

  • 사용하다req.ip또는req.ips.req.connection.remoteAddress이 솔루션에서는 작동하지 않습니다.
  • 에 대한 추가 :'trust proxy'만약 당신이 통과된 모든 것을 믿는 것보다 더 정교한 것이 필요하다면 이용할 수 있습니다.x-forwarded-for헤더(예: 프록시가 신뢰할 수 없는 소스에서 기존의 x-syslog-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;

소문자 헤더를 표현하는 참고

타사 라이브러리를 사용해도 괜찮으시다면요.request-ip을 확인하실 수 있습니다.

사용할 수 있는 방법은

import requestIp from 'request-ip';

app.use(requestIp.mw())

app.use((req, res) => {
  const ip = req.clientIp;
});

소스 코드가 꽤 길어서 여기에 복사하지 않겠습니다. https://github.com/pbojinov/request-ip/blob/master/src/index.js 에서 확인할 수 있습니다.

기본적으로,

요청에서 특정 헤더를 찾고 헤더가 없으면 일부 기본값으로 돌아갑니다.

사용자 IP는 다음 순서에 따라 결정됩니다.

  1. X-Client-IP
  2. X-Forwarded-For(헤더는 "클라이언트 IP, 프록시 1 IP, 프록시 2 IP" 형식으로 여러 IP 주소를 반환할 수 있으므로 첫 번째 IP 주소를 사용합니다.)
  3. CF-Connecting-IP(클라우드 플레어)
  4. Fastly-Client-Ip기능으로 시 신속하게 및 )(CDN 및 Firebase 호스팅)
  5. True-Client-Ip 및 Akamai 및 Cloudflare)
  6. X-Real-IP 프록시Nginx 파일/FastCGI)
  7. X-Cluster-Client-IPLB, 스팅레이예: LB, 리버베드 스팅레이)
  8. X-Forwarded,Forwarded-For그리고.Forwarded)(#2의변형)
  9. req.connection.remoteAddress
  10. req.socket.remoteAddress
  11. req.connection.socket.remoteAddress
  12. req.info.remoteAddress

수 주소를 합니다.null.

공개:저는 도서관과 관련이 없습니다.

특히 노드의 경우 이벤트 연결 시 http 서버 구성 요소에 대한 설명서에 다음과 같이 나와 있습니다.

[Triggered](트리거됨) - 새 TCP 스트림이 설정된 경우[소켓]은 네트 유형의 물체입니다.소켓. 일반적으로 사용자는 이 이벤트에 액세스하지 않습니다.특히 프로토콜 파서가 소켓에 연결되는 방식 때문에 소켓에서 읽을 수 있는 이벤트가 발생하지 않습니다.소켓은 에서 액세스할 수도 있습니다.

그것은 그말은, 서래그를 의미합니다.request.connection는 소켓이며 설명서에 따르면 실제로 다음과 같은 socket.remoteAddress 특성이 있습니다.

원격 IP 주소의 문자열 표현입니다.예를 들어 '74.125.127.100' 또는 '2001:4860:a005:68'입니다.

express에서 요청 개체는 Node http 요청 개체의 인스턴스이기도 하므로 이 접근 방식은 계속 작동합니다.

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

req.ip

원격 주소를 반환하거나 "신뢰 프록시"가 사용 가능한 경우(업스트림 주소).

요구.입

"신뢰 프록시"가 다음과 같은 경우true"X-Forwarded-For" IP 주소 목록을 구문 분석하고 배열을 반환합니다. 그렇지 않으면 빈 배열이 반환됩니다.예를 들어 값이 "client, proxy1, proxy2"인 경우 배열 ["client", "proxy1", "proxy2"]이 표시됩니다. 여기서 "proxy2"는 가장 다운스트림입니다.

아는 가 도 모릅니다.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여느 때와 같은 방법으로

답변에 대한 추가 정보입니다.

사중인경우를 .nginx당신은 덧붙일 것입니다.proxy_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;
    }
}

를 다시 한 후nginx은 당신의 IP 주소에 있는 IP 주소에 할 수 것입니다.node/express응프로램경이 있는 응용 req.headers['x-real-ip'] || req.connection.remoteAddress;

저는 이 질문에 답했다는 것을 알고 있지만, 제 질문을 어떻게 해결했는지는 다음과 같습니다.

let ip = req.connection.remoteAddress.split(`:`).pop();

저는 그 목적으로 소포를 작성했습니다.고속 미들웨어로 사용할 수 있습니다. 패키지는 여기에 게시됩니다. https://www.npmjs.com/package/express-ip

다음을 사용하여 모듈을 설치할 수 있습니다.

npm i express-ip

사용.

const express = require('express');
const app = express();
const expressip = require('express-ip');
app.use(expressip().getIpInfoMiddleware);

app.get('/', function (req, res) {
    console.log(req.ipInfo);
});

대리인 뒤에 있는 익스프레스에 따르면,req.ip 역방향 를 이 되었습니다.trust proxy적절히.그러므로 그것은 보다 낫습니다.req.connection.remoteAddress네트워크 계층에서 가져오지만 프록시를 알지 못합니다.

저의 경우, 이 솔루션과 유사하게 다음과 같은 x-forwarded 방식을 사용하게 되었습니다.

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

x-forwarded-for헤더는 오리진에서 최종 대상 서버까지 계속해서 IP의 경로를 추가하므로 오리진 클라이언트의 IP를 검색해야 할 경우 이 항목이 어레이의 첫 번째 항목이 됩니다.

이것은 다른 것들보다 저에게 더 효과적이었습니다. 뒤에 CloudFlare가 한 것 .cf-connecting-ip.

req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress

프록시 뒤에서 Express를 테스트하지 않았습니다. 이에 대해 아무 말도 하지 않았기 때문입니다.cf-connecting-ip표제의

varip = req.connection.remoteAddress;

ip = ip.http:)[3];

헤더 개체에는 필요한 모든 것이 있습니다. 다음을 수행하십시오.

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

could-flare, nginx 및 x-real-ip 지원 포함

var user_ip;

    if(req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
      let first = req.headers['cf-connecting-ip'].split(', ');
      user_ip = first[0];
    } else {
      let user_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }

k @kakopappa 솔루션 플러스로 모두 합치는 것.morgan클라이언트 IP 주소 로깅:

morgan.token('client_ip', function getId(req) {
    return req.client_ip
});
const LOG_OUT = ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :client_ip'
self.app.use(morgan(LOG_OUT, {
    skip: function(req, res) { // custom logging: filter status codes
        return res.statusCode < self._options.logging.statusCode;
    }
}));

// could-flare, nginx and x-real-ip support
var getIpInfoMiddleware = function(req, res, next) {
    var client_ip;
    if (req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
        var first = req.headers['cf-connecting-ip'].split(', ');
        client_ip = first[0];
    } else {
        client_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }
    req.client_ip = client_ip;
    next();
};
self.app.use(getIpInfoMiddleware);

언급URL : https://stackoverflow.com/questions/10849687/express-js-how-to-get-remote-client-address

반응형