Main problem
How can I create in express a new request to Google Cloud Functions containing the same IP address as the original client request?
Or, how can I proxy the client request through express to Google Cloud Functions by preserving the IP address, so Google Cloud Functions shows me the client IP instead of the IP address of the nodejs server.
The code
Express app
// app.js
const express = require('express');
const request = require('request');
const nocache = require('nocache');
const cors = require('cors');
const API_ENDPOINT = 'https://project-name.cloudfunctions.net/cloudfunction-name';
const app = express();
const port = 3000;
app.use(nocache());
app.use(cors());
app.get('/test', function (req, res) {
req.pipe(
request({
qs:req.query,
uri: API_ENDPOINT,
json: true,
gzip: true,
ip: req.ip
}, (error, response, body) => {
console.log(body)
console.log(req.ip)
})
).pipe(res);
});
app.listen(port, function () {
console.log('Example app listening on port ' + port +'!');
});
CloudFunctions
const cors = require('cors')
const localeCode = require('locale-code');
function location(req, res) {
let languages = req.acceptsLanguages();
let lang = '';
if(languages.length > 0){
lang = localeCode.getLanguageCode(languages[0]);
}
let data = {
country: req.headers["x-appengine-country"].toLowerCase(),
region: req.headers["x-appengine-region"].toLowerCase(),
city: req.headers["x-appengine-city"].toLowerCase(),
userIP: req.headers["x-appengine-user-ip"],
language: lang
};
// Json response is gzipped by CloudFunctions
res.json(data)
}
exports.init = (req, res) => {
const corsHandler = cors({ origin: true })
return corsHandler(req, res, function() {
return location(req, res);
});
};
CloudFunctions Request looks like this. (Json is passed in the request "body")
{
country: "de",
region: "he",
city: "frankfurt",
userIP: "35.xxx.xxx.xxx",
language: "de",
}
What I've tried so far
I've searched for hours and couldn't find any example, how this can be achieved.
According to my understanding, this code portion should pipe (proxy) the client request to the CloudFunctions api and back to the requester (express app) by preserving the request.
req.pipe(
request({
qs:req.query,
uri: API_ENDPOINT,
json: true,
gzip: true,
ip: req.ip
}, (error, response, body) => {
console.log(body)
console.log(req.ip)
// Here comes the logic for redirecting clients
})
).pipe(res);
Also adding or removing this snippet below makes no difference. The userIP in the response object allways contains the server IP instead of the client IP.
ip: req.ip