Get User IP Address when Server is Proxied by Cloudflare

If your server is proxied by Cloudflare, chances are the built-in method to get the user IP Address in AdonisJS is returning Cloudflare's IP instead of your users. With this snippet, we'll fix that!

Published
Oct 21, 23

Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.

Adocasts

Burlington, KY

If your server is proxied through Cloudflare, they're handling your requests before passing it along to your server. When they do this, the traditional IP Address property (request.request.socket.remoateAddress) will come from Cloudflare's servers.

Meaning, if you run the AdonisJS method to fetch the user's IP Address request.ip(), you'll instead get the IP Address of the Cloudflare server that handled the request. I ran into this fun little, production only, issue while writing Adocasts' session tracking feature (screenshotted below).

Adocasts session tracking

Thankfully, we do have a couple locations that we can use to get our user's real IP Address.

Note, if you're an enterprise Cloudflare user, you have access to the True-Client-IP header.

CF-Connecting-IP

Cloudflare will pass along with the proxied request a new header called CF-Connecting-IP which will contain the client IP Address that connected to Cloudflare's server; meaning your user's IP Address.

Note, there's also an IPv6 version of this header as well. Cf-Connecting-IPv6.

Route.get('/', async ({ request }) => {
  const ip = request.header('CF-Connecting-IP')
  return ip
})
Copied!

You can find more info about this via Cloudlfare's documentation.

X-Forwarded-For

The X-Forwarded-For header will contain both Cloudflare's proxy server IP Address and your user's original IP Address. They'll be provided as a comma delimited list and through my testing it seems like the user's IP Address will come first.

Note, Cloudflare does recommend using CF-Connecting-IP over X-Forwarded-For when available.

Route.get('/', async ({ request }) => {
  let ip = request.header('CF-Connecting-IP')

  if (!ip) {
    ip = request.header('X-Forwarded-For')?.split(',').at(0)
  }

  return ip
})
Copied!

Again, you can find more about this too, via Cloudflare's documentation.

Join The Discussion! (0 Comments)

Please sign in or sign up for free to join in on the dicussion.

robot comment bubble

Be the first to Comment!