awesome-fc / webserverless

Serverless based web development framework
MIT License
31 stars 8 forks source link

cannot access client ip from req.ip #13

Open RE-Roger opened 4 years ago

RE-Roger commented 4 years ago

client IP is stored at request.headers['HTTP_CLIENT_IP']. I naturally think I can access the client IP from express req.ip, but I can't. Seems the project filter this header. I think this feature is necessary.

haolei commented 4 years ago

before request to httpProxy, set client ip manually req.headers.clientIP = req.clientIP; server.httpProxy(req, res, context);

newbaluku commented 4 years ago

before request to httpProxy, set client ip manually req.headers.clientIP = req.clientIP; server.httpProxy(req, res, context);

Tried, but doesn't work. You manage to get it to work?

RE-Roger commented 4 years ago
const { Server } = require('@webserverless/fc-express')
const app = require('./dist/server.js');

const server = new Server(app);
module.exports.handler = function(req, res, context) {
    req.headers['HTTP_CLIENT_IP'] = req.clientIP
    server.httpProxy(req, res, context);
};

This is how I solved it, I store IP in request.headers['HTTP_CLIENT_IP'], but I think this should be done by this package.

newbaluku commented 4 years ago

@RE-Roger Thanks for the response.

I followed but still getting req.ip === undefined in my Express code. My code below:

const { Server } = require('@webserverless/fc-express')
const { app } = require('./app');

const server = new Server(app);

exports.handler = (req, res, context) => {
  console.log('handler> req.clientIP:', req.clientIP)
  console.log('handler> req.headers.clientIP:', req.headers.clientIP)
  req.headers['HTTP_CLIENT_IP'] = req.clientIP;
  console.log('handler> req.headers[HTTP_CLIENT_IP]:', req.headers['HTTP_CLIENT_IP'])
  try {
    server.httpProxy(req, res, context);
  }
  catch (e) {
    console.log('handler> server.httpProxy failed:', e);
  }
};

I wonder what version of the library are you using? Mine was:

  "dependencies": {
    "@webserverless/fc-express": "^0.1.4",
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "express-sanitizer": "^1.0.5",
    "helmet": "^4.1.1",
  }
RE-Roger commented 4 years ago

@newbaluku This library does not handle IP part for you, that's why I opened this issue. You need to get IP from the request headers you have set previously. Like the middleware below,

router.all('*', function (req, res, next) {
    if (!req.ip) {
        req.ip = req.headers['http_client_ip']; //req.ip is read-only, this line is invalid
    }
    next();
})

I haven't read through the express code, so I don't know the details about how express extract IP from the http request, maybe there is a header or something to let express handle the IP itself. But I do believe this should be done by the library.

newbaluku commented 4 years ago

@RE-Roger Thanks, I see. But for some reason, I can't seems to be able to set req.ip. This field seems to be read-only to me.

app.use((req, res, next) => {
  if (!req.ip) {
    req.ip = 123;//req.headers['x-client-ip'];
    console.log('set req.ip to 123:', req.ip)
    req.ip1= req.headers['x-client-ip'];
  }
  else {
    console.log('NO set req.ip:', req.ip)
  }
  next();
});

console output:

set req.ip to 123: undefined
set req.ip1: 18x.1x9.x2.xx4

but setting variable of a different name works.

Separately, I have also investigated the header value of X-Forwarded-For and found that it's undefined. Maybe the problem lies here where the gateway/proxy doesn't pass on the ip address to the function compute instance and causes Express's req.ip to be undefined.

RE-Roger commented 4 years ago

@newbaluku Thanks for pointing out my error, the code I wrote is just for demonstration, I haven't checked them.