graphql-mesh icon indicating copy to clipboard operation
graphql-mesh copied to clipboard

Forward Client RemoteIP

Open gsingh-ds opened this issue 2 years ago • 10 comments

Hello There,

We are using GraphQL Mesh in front of GRPC. We want to forward request remote ip (customer ip) to the backend. Seems like there is no way to do it with GraphQL Mesh at this point, please correct me if I am wrong.

gsingh-ds avatar May 17 '22 11:05 gsingh-ds

There is no "forwarding" mechanism in GraphQL Mesh because GraphQL Mesh gives you a gateway schema that is served with a GraphQL Server. So in GraphQL, the execution is seperated from the HTTP pipeline. That means you cannot assume that the client is always from HTTP etc etc. So, you can define custom metadata to pass some information from the request like below; (In this case, the consumer is responsible of providing this data. I assume that you are using HTTP server)

sources:
   - name: MyGRPC
     ...
     metaData:
         someHeaderInfo: ["headers", "some-header"]

I will create a PR to add this to our docs :)

I'll also add support for interpolation syntax like below;

sources:
   - name: MyGRPC
     ...
     metaData:
         someHeaderInfo: "{context.req.headers['some-header']}"

Thank you for reminding us for missing documentation :)

ardatan avatar May 17 '22 12:05 ardatan

Documents have been added! Let us know if it doesn't work for you!

ardatan avatar May 17 '22 23:05 ardatan

Well, I understand why this is a problem but our application needs the client IP to work. Using headers to do so is risky that it can be tempered with. Do you think there is any way or hack to get this done?

gsingh-ds avatar May 18 '22 05:05 gsingh-ds

req.ip should also have the IP address of the client.

ardatan avatar May 18 '22 15:05 ardatan

So here is the setup request comes from user then to GraphQL server and then hits out backend server . user -- > graphql --> grpcserver

I used your method , I added new header in mesh config. like testheader: ["req", "ip"]

When I log this header in grpcserver it shows 127.0.0.1 I am expecting user ip

gsingh-ds avatar May 19 '22 07:05 gsingh-ds

If you are testing this by calling the local server, it is expected to get 127.0.0.1. Also if you serve Mesh behind the proxy, you can only access the real address with x-forwarded-for header. req is NodeJS Incoming Message object by the way. You can take a look at their docs to learn more. For the future reference, those are not actually Mesh features. When you use Mesh with a server that exposes request object within context. Those are the only things I can suggest.

ardatan avatar May 19 '22 11:05 ardatan

So our service is deployed on AWS App mesh. There is Virtual Gateway and envoy proxy infront of graphql mesh. ref image: https://i.stack.imgur.com/ibY5P.png. I have tried x-forward-for header, seems like envoy does not send it.

gsingh-ds avatar May 20 '22 08:05 gsingh-ds

Mesh basically uses Node.js, Express.js and Yoga. Hmm maybe ['req', 'socket', 'remoteAddress'] ??

ardatan avatar May 20 '22 13:05 ardatan

I think I tried with ['req', 'connection', 'remoteAddress']. I will test your recommendation today. I hope it will work.

gsingh-ds avatar May 20 '22 13:05 gsingh-ds

Well, It did not work I think because of envoy proxy as a side car, the output of ['req', 'socket', 'remoteAddress'] comes out to be 127.0.0.1. Well, my only hope is to get X-Forward-For header from envoy proxy at this time. If you have any other recommendations. Please let me know.

gsingh-ds avatar May 20 '22 13:05 gsingh-ds

IP information depends on the environment. There is no standard way to get the remote ip. If you are behind a proxy, you can get it from req.headers['x-forward-for']. So this is not a bug in Mesh actually. Closing the issue.

ardatan avatar Mar 31 '23 06:03 ardatan