简体   繁体   中英

NodeJS - Return client ip address instead of server's

Problem Information

I'm using cors to make sure that only specific IP's can GET and POST data on my REST API.

The IP that is returned , everytime someone want to GET or POST data, is the IP of the server where the application is hosted on, not the person's own IP address.

At this moment everyone can access the REST API because my front-end is running on the same server, the front-end needs to have the permission to GET and POST data so I whitelisted the server's IP address.

Since everyone, who's trying to connect, its ip address is automatically the server's address, everyone has access the REST API.

Technical Information

My REST API is running using pm2 on port 8080, I re-route it using Nginx to port 8877 that's using SSL. The 8877 is the endpoint of my rest api, perhaps that's the reason why the client ip address is automatically the server's ip address?

# General HTTP to HTTPS
server {
        listen 80;
        listen [::]:80;
        server_name www.example.com default_server;

        location / {
                return 302 https://$host$request_uri;
        }
}

#Web Application
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name www.example.com default_server;

    root /var/www/example.com;
    index index.html;

    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_certificate /etc/nginx/ssl/example.com/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com/example.com.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    location / {
                #...
                try_files $uri $uri/ /index.html$is_args$args;
                #...
    }
}

#Rest API http to https 
server {
    listen 8877 ssl;
    listen [::]:8877 ssl;
    server_name example.com;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_certificate /etc/nginx/ssl/example.com/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com/example.com.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    location / {
            proxy_pass http://example.com:8080;
    }
}

Rest API cors

const whitelist = [
    '::ffff:111.11.11.111', etc.];

var corsOptions = {
    origin: (origin, callback) => {
        let trafficAllowed = {};
        console.log("IP: ", origin);
        if (whitelist.indexOf(origin) !== -1) {
            trafficAllowed = {origin: false}
        } else {
            trafficAllowed = {origin: true}
        }
        callback(null, trafficAllowed)
    }
};

app.use((req, res, next) => {
    req.headers.origin =
        req.connection.remoteAddress ||
        req.headers['x-forwarded-for'] ||
        req.socket.remoteAddress ||
        (req.connection.socket ? req.connection.socket.remoteAddress : null);
    next();
});

app.use(cors(corsOptions));

Possible ways to solve it

  • Is it possible to assign SSL directly to the 8080 port (the REST API is using pm2)?
  • How to get the client's ip address instead of the server his.

Try putting these configurations in your nginx:

proxy_set_header X-Real-IP $remote_addr; 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;

Without this, your backend will only receive nginx IP address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM