Django: get client IP from behind Amazon Elastic Load Balancer

July 13, 2016

Last update: March 22, 2020

Tested with Django 1.9 and newer, 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)

References

  1. HTTP Headers and Classic Load Balancers

  2. HttpRequest.META


A photo of Elia Contini
Written by
Elia Contini
Sardinian UX engineer and a Front-end web architect based in Ticino, Switzerland. Marathoner, traveller, wannabe nature photographer.