IP address of the remote origin of the request

Hi, I’m testing the Workers in the Playground available to all users and it seems the Request object does not have information about the connection and socket object. What I need is the IP address of the remote origin of the request:

const ip = req.headers['x-forwarded-for'] || 
 req.connection.remoteAddress || 
 req.socket.remoteAddress ||
 (req.connection.socket ? req.connection.socket.remoteAddress : null);

Will this code work in the Beta and Production release of Workers? Or am I doing anything wrong and there is a different way to get the origin IP address?

Thank you!

1 Like

Hi @diego.parrilla.santa,

The original visitor’s IP address is available in the ‘CF-Connecting-IP’ header – you should find it available in both the Cloudflare Workers Playground, and via the editor in beta/production.

Note that Cloudflare Workers implements the Fetch API, meaning our Request and Headers objects have the same interface as those found in browsers, not Node’s HTTP module, which it looks like you may have expected. Specifically:

  • Headers are not stored as properties, so to access them you’ll need to call req.headers.get('header-name'). Note that will return null if no such header exists – to specifically test for the presence of a header, you can use req.headers.has('header-name').

  • To dump all the headers stored in a Headers object when you’re in the Playground, you can use the following trick: console.log(new Map(req.headers)).

  • Request (and Response) objects have no connection or socket properties.

You can read more about these topics at these links. Let me know if you have any questions!



Than you very much for the tip! Yes, I thought it was like AWS Lambda@Edge and needed to code Node’s HTTP module. But thanks to your hints I have tested successfully the Cloudflare Workers with our API and it works like a charm!

You can find here a gist with the code: Using Cloudflare Workers and https://Apility.io API add to the request headers information of the blacklists of abusers that contains the IP address of the client. · GitHub

The code adds two new headers to the request: Apilityio-Badip and Apilityio-Elapsed-Time. Apilityio-Badip is a list of blocklist names of IP addresses that have included the IP address of the remote client, and Apilitio-Elapse-Time is the milliseconds it took to perform the request to our service endpoint (always below 80ms, awesome!).

My company Apility.io has an API for developers to know if an IP, domain or email could be used to ‘abuse’ of a service. I think that a solution like Cloudflare Workers working at the edge of the network is a very simple and elegant way to give this information to the application or service without the hassle of a code integration. In the coming weeks, we will probably write on our blog about it, because it’s really cool.

Again, thank you very much for the support!

1 Like

Diego, I’m glad to help, and thank you for sharing the code you came up with!

1 Like

Thanks so much for this reply. It was very helpful, figuring out where to get the ip address from.

Just to note for others running into the same problem.

The playground no longer has the cloudflare ip headers in there.

The playground only has two headers now

x-forwarded-proto => https
host => raspy-wood-…workers.dev

So if you want to get the ip address, you’ll need to deploy the app and visit your worker in production.

Here is some code to view all the headers in production.

addEventListener('fetch', event => {
* Respond to the request
* @param {Request} request
async function handleRequest(e) {
   let a = '';
   for (const element of e.headers) {
       a = a.concat(element[0], " => ", element[1], "\n")
 var host = e.headers.get("host")
 return new Response(a, {status: 200})

Then you will see the real headers available in production:

accept => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
accept-encoding => gzip
accept-language => …
cf-connecting-ip => 2…
cf-ipcountry => US
cf-ray => 620…
cf-request-id => 0833…
cf-visitor => {“scheme”:“https”}
connection => Keep-Alive
cookie => __cfduid=d4f…
host => rasp…
upgrade-insecure-requests => 1
user-agent => Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0
x-forwarded-proto => https
x-real-ip => …

1 Like