BackendStack21 / fast-gateway

Fast-gateway is an easy to use Node.js API gateway framework built to handle large scale API traffic with great performance and scalability. Written with JavaScript, it is a framework for the masses!
MIT License
311 stars 35 forks source link

Preserving Client IP Address #63

Closed monmallonga closed 3 years ago

monmallonga commented 3 years ago

Hi,

I'm currently trying out fast-gateway, but i am currently having problems in preserving the client ip address. I always seem to get the ip address of the gateway? Is there anything wrong with my configuration? Hopefully you can help me out on this

const fs = require('fs');
const path = require('path');
const https = require('https');
const rateLimit = require('express-rate-limit');
const requestIp = require('request-ip');
const gateway = require('fast-gateway');
const config = require('./config');
const { error } = require('console');
const port = config.gatewayPort;
const key = config.privateKeyLocation;
const cert = config.serverCertLocation;
const ca = config.caCertLocation;
const app = require('restana')({
    server: https.createServer({
        key: fs.readFileSync(key, 'ascii'),
        cert: fs.readFileSync(cert, 'ascii'),
        ca: fs.readFileSync(ca, 'ascii'),
    }),
});
const allowlist = config.allowList;
const corsOptionsDelegate = function (origin, callback) {
    let corsOptions;
    let filtered = 'https://localhost:3000';
    if (allowlist.indexOf(origin) !== -1 || allowlist.indexOf(filtered) !== -1) {
        corsOptions = { origin: true }; // reflect (enable) the requested origin in the CORS response
    } else {
        corsOptions = { origin: false }; // disable CORS for this request
    }
    callback(corsOptions.origin ? null : new Error('Error'), corsOptions); // callback expects two parameters: error and options
};
const server = gateway({
    server: app,
    middlewares: [
        require('helmet')(),
        (req, res, next) => {
            res.setHeader('Access-Control-Allow-Credentials', true);
            res.setHeader('Access-Control-Allow-Origin', allowlist);
            next();
        },
        require('cors')({ origin: corsOptionsDelegate }),
        // first acquire request IP
        (req, res, next) => {
            req.ip = requestIp.getClientIp(req);
            return next();
        },
        // second enable rate limiter
        rateLimit({
            windowMs: 1 * 60 * 1000, // 1 minute/s
            max: 160, // limit each IP to 60 requests per windowMs
            handler: (req, res) =>
                res.send('Too many requests, please try again later.', 429),
        }),
    ],
    routes: [
        {
            prefix: '/api1',
            target: 'http://localhost:3001',
        },
        {
            prefix: '/api2',
            target: 'http://localhost:3002',
        },
        {
            prefix: '/api3',
            target: 'http://localhost:3003',
        },
        {
            prefix: '/api4',
            target: 'http://localhost:3004',
        },
        {
            prefix: '/api5',
            target: 'http://localhost:3005',
        },
        {
            prefix: '/api6',
            target: 'http://localhost:3006',
        },
        {
            prefix: '/api7',
            target: 'http://localhost:3007',
        },
    ],
});
server.start(port).then(() => {
    console.log('Server running at https://localhost:' + port);
}); 
jkyberneees commented 3 years ago

Hi @monmallonga, fast-gateway does not automatically forwards the client IP address. To achieve this, you would need to populate the client IP as a custom header (commonly X-Forwarded-For) before the gateway forwards the request, you can use custom middlewares...

Regards