I am working on a Django project where users will have custom info given to them depending on their location. In order to do this, I use their IP address to identify their country. In order to keep data in the database consistent, I need to make sure I have an accurate IP.
I understand that using META usually uses headers sent by the client's browser, but I don't know if that applies to the REMOTE_ADDR
attribute.
TLDR: what is the difference between HttpRequest.get_host()
and HttpRequest.META['REMOTE_ADDR']
?
The difference between HttpRequest.get_host()
and HttpRequest.META['REMOTE_ADDR']
is that the first one checks IP in the following headers in order of decreasing preference:
HTTP_X_FORWARDED_HOST
HTTP_HOST
SERVER_NAME combined with SERVER_PORT
whereas the second one check the IP in the header REMOTE_ADDR
.
There is a huge difference in the type of information returned: get_host()
will give you the name of the server hosting your application, not the IP of the client.
More in detail, here is the implementation of get_host()
:
def get_host(self):
"""Returns the HTTP host using the environment or request headers."""
# We try three options, in order of decreasing preference.
if settings.USE_X_FORWARDED_HOST and (
'HTTP_X_FORWARDED_HOST' in self.META):
host = self.META['HTTP_X_FORWARDED_HOST']
elif 'HTTP_HOST' in self.META:
host = self.META['HTTP_HOST']
else:
# Reconstruct the host using the algorithm from PEP 333.
host = self.META['SERVER_NAME']
server_port = str(self.META['SERVER_PORT'])
if server_port != ('443' if self.is_secure() else '80'):
host = '%s:%s' % (host, server_port)
allowed_hosts = ['*'] if settings.DEBUG else settings.ALLOWED_HOSTS
domain, port = split_domain_port(host)
if domain and validate_host(domain, allowed_hosts):
return host
else:
msg = "Invalid HTTP_HOST header: %r." % host
if domain:
msg += "You may need to add %r to ALLOWED_HOSTS." % domain
raise DisallowedHost(msg)
If you want to check for client IP address, here are some headers that could be worth checking (see Getting the client IP address: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, what else could be useful?):
REMOTE_ADDR
HTTP_X_FORWARDED_FOR
HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
can be comma delimited list of IPsHTTP_X_FORWARDED
HTTP_X_CLUSTER_CLIENT_IP
HTTP_FORWARDED_FOR
HTTP_FORWARDED
If you don't know which one to pick (if not all), you could log those headers and pragmatically add new checkings over time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With