<p><pre><code> const realClientIpAddress = (req.headers['x-forwarded-for'] || req.ip || "").split(',')
const ip = realClientIpAddress[realClientIpAddress.length - 1]
</code></pre>
X-Forwarded-For is appended-to for every proxy the request passes through. You want the first IP address, not the last one.<p>Example, if your app was on Heroku behind Cloudflare, the request will look like this:<p>IP: <Heroku's load balancer addr><p>X-Forwarded-For: <Real user addr>, <Cloudflare addr><p>Your code, as written, will be geolocating the Cloudflare node.
I run <a href="https://freegeoip.app" rel="nofollow">https://freegeoip.app</a> for some time now, if anyone is interested in a free hosted solution.
The problem with geoip is that the free services will never be as good as the paid services, and the paid ones aren't all that accurate either.<p>For just about every geoip use case, there is a better solution. Namely, almost every modern phone and desktop is capable of providing it's location, and is more accurate than any geoip database.<p>The main issue is that people can make their device lie about it's location, so if you're using geoip for security (say you're a streaming service) then that's about the only valid use case, and that only exits because studios still want to live in a world where borders matter.
We made a similar app called geoip - <a href="https://git.cloudron.io/cloudron/geoip" rel="nofollow">https://git.cloudron.io/cloudron/geoip</a> . It also uses maxmind's db. Supports json and jsonp as well. You can try it at <a href="https://geolocation.cloudron.io/json" rel="nofollow">https://geolocation.cloudron.io/json</a> . Please don't use this as a 'service', install your own :)<p>BTW, do you use geolite or geolite2 db? The former is getting deprecated next month.
I started IPinfo.io ~6 years (and launched it on HN: <a href="https://news.ycombinator.com/item?id=7239333" rel="nofollow">https://news.ycombinator.com/item?id=7239333</a>). We now serve 20 billion geolocation API requests a month, and roll our own geolocation data (we used to rely on the maxmind data, but have been busy working on improvements to that, and then our own complete data, along with other data sets like IP usage type, company and carrier etc).
GeoIP is pretty accurate at the state/country level for most users, but you will run into precision issues at the city level.<p>A bigger problem seems to be that many forget to continuously sync their IP DB with their provider. Your targeting is only as good as your IP -> Geo map.<p>My team built a tool for testing GeoIP implementations here: <a href="https://www.geoscreenshot.com" rel="nofollow">https://www.geoscreenshot.com</a> to get around the issue of testing if it works.
If you're interested in a service with a free tier and more specific granularity than the MaxMind free database, Geocodio has a pretty nice service. They also have a bunch of different enrichment options that you can tack on if you need things like congressional districts or school districts. It's a really nice service.<p><a href="https://www.geocod.io/" rel="nofollow">https://www.geocod.io/</a><p>(not affiliated, just a fan)
A similar service is Am I Mullvad’s API. Not sure if they use MaxMind, however.<p><a href="https://am.i.mullvad.net/api" rel="nofollow">https://am.i.mullvad.net/api</a>
I always feel a need to state this to folks who are not aware of geolocation and ip addresses: Geolocation based on IP is very unreliable and should be used only for soft-analytics at best.<p>Example: It is not fit for security postures (in theory). One can dump all the CURRENT v4 routes being advertised out of China and block them via blackholes/firewalls/etc. However immediately after that a rogue operator could hijack a non-China affiliated prefix, use it for badness, and then release the hijacked prefix.<p>Most Geolocation services that are static (point in time) will not detect the above scenario. BGP-based monitoring services will, but that's a step up $$$ wise.