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 IPs
HTTP_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.