As a general rule, a website does not have to worry about its hosting infrastructure. And yet, there is a special case for which a web developer must understand the network environment around the server machine: when it is necessary to retrieve its visitors' IP address.
The task seems simple since the webserver knows its visitors' IP addresses, which can be retrieved from one of its variables. And yet, there are complications.
The request object available in Rails controllers exposes many helpful methods to get information about the client's request (the visitor of your site). You can use the request.ip method to get the IP address of the visitor, and we will observe some peculiarities:
Obviously, if you run this code on your local machine, and depending on its configuration, the page will display "Your IP address is 127.0.0.1" or "Your IP address is ::1". The first case corresponds to a IPv4 address, and the second to a IPv6 address. The two addresses have in common that they are both a loopback addresses, which are used by any computer to connect to itself.
To get a more interesting result, you have to deploy your code on a public server at a hosting company. Once this is done, get your real public IP address using a third party service as a reference. You can find such a service on Google. Then access your site to compare the results. If everything went well, your script would show you the same IP address as the one given by the third party service.
As a web developer, you may have already heard of load-balancer, DDoS mitigator, or more simply proxy or firewall. You may not have bothered until now to understand how they work. But to get the IP address of your visitors, you will need to understand some of the basic mechanisms.
A proxy or firewall is positioned between your web server and your visitor. Its role is to protect your web server, which is certainly configured only to accept connections that have been filtered by the proxy.
In such a configuration, if you run the script we wrote above, you will get an address that doesn't match your IP address, and if you search a little deeper, you will quickly understand that it corresponds to the IP address of the proxy. Indeed, the proxy modifies the client request to make your server believe that it is the request's origin. The proxy thus ensures that all communications pass through it.
In this case, you will have to use the remote_ip method, which is also available in the controllers, verifying that the IP address has been changed by a proxy and returning the client's real address. Here is how to modify your script:
From now, if you connect to your server, you will see your real IP address.
If you connect to the Internet through a VPN service and access your IP address detection script, you will find that the address displayed is not your real address but the VPN's exit address.
Since VPN is a service to protect Internet users, they make sure to prevent websites from discovering their users' real IP address. As a result, your script won't determine if the user is behind a VPN server or not, and therefore it will be impossible for you to know if the IP address thus obtained is real.
To do this, it is necessary to use a service that analyzes the IP addresses of your visitors and determines, among other things, whether this address corresponds to an exit address of a VPN service. You may be able to develop such a service by yourself, but you would have to update the list of VPNs' list of known IPs constantly, which is extremely time-consuming.
Abstract provides such a service for free, responding very fast and always up to date, through the geolocation API. Just create an account in a few seconds, which gets you your private API key. Then a simple HTTP call allows you to determine if the visitor is behind a VPN.