Django: get client IP from behind Amazon Elastic Load Balancer
July 13, 2016Last update: May 23, 2021
Tested with Django 2.2 LTS and 3.2 LTS, it works even with Application Load Balancers
The problem
We want to get the client IP when our Django project is running on different nodes behind an Amazon Elastic Load Balancer. If we use the code below:
from django.http import HttpResponse
def get_ip(request):
ip = request.META['REMOTE_ADDR']
return HttpResponse(ip)
the value of the ip
variable is the IP of load balancer. Definetely
not what we are looking for.
A solution
According to Elastic Load Balancer documentation the original IP of the client is stored and forwarded to nodes in a HTTP header called X-Forwarded-For
. So to obtain the real client IP we have to add these lines to our code:
from django.http import HttpResponse
def get_ip(request):
ip = request.META['REMOTE_ADDR'] # during development
if 'HTTP_X_FORWARDED_FOR' in request.META: # load balancer
ip = request.META['HTTP_X_FORWARDED_FOR']
return HttpResponse(ip)
We have to keep in mind this part of the offial documentation:
The X-Forwarded-For request header may contain multiple IP addresses that are comma separated. The left-most address is the client IP where the request was first made. This is followed by any subsequent proxy identifiers, in a chain.
If needed, we can split the content HTTP_X_FORWARDED_FOR
and get the first element.