6

Heroku proxies requests from a client to server, so you have to parse the X-Forwarded-For to find the originating IP address.

The general format of the X-Forwarded-For is:

X-Forwarded-For: client1, proxy1, proxy2

Using werkzeug on flask, I'm trying to come up with a solution in order to access the originating IP of the client.

Does anyone know a good way to do this?

Thank you!

Jack P.
  • 727
  • 1
  • 7
  • 11

2 Answers2

15

Werkzeug (and Flask) store headers in an instance of werkzeug.datastructures.Headers. You should be able to do something like this:

provided_ips = request.headers.getlist("X-Forwarded-For")
# The first entry in the list should be the client's IP.

Alternately, you could use request.access_route (thanks @Bastian for pointing that out!):

provided_ips = request.access_route
# First entry in the list is the client's IP
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • 1
    you might want to check http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.BaseRequest.access_route – Bastian Apr 04 '12 at 12:19
  • @Bastian the link you posted says "if forwarded header exists" which I understand would be `X-Forwarded-For` , so in case forwarded header does not exists would the access_route function will work , I do not have any place to test my flask app other than heroku. – Ciasto piekarz Aug 08 '17 at 19:16
3

This is what I use in Django. See this https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_host

Note: At least on Heroku HTTP_X_FORWARDED_FOR will be an array of IP addresses. The first one is the client IP the rest are proxy server IPs.

in settings.py:

USE_X_FORWARDED_HOST = True

in your views.py:

if 'HTTP_X_FORWARDED_FOR' in request.META:
    ip_adds = request.META['HTTP_X_FORWARDED_FOR'].split(",")   
    ip = ip_adds[0]
else:
    ip = request.META['REMOTE_ADDR']
temoto
  • 5,394
  • 3
  • 34
  • 50
David Dehghan
  • 22,159
  • 10
  • 107
  • 95
  • 1
    Please read [this note about the last IP in `X-Forwarded-For` being the only reliable one on Heroku](http://stackoverflow.com/a/18517550/429091) (unless you trust clients from outside of Heroku to not lie about themselves… – binki Jul 04 '16 at 04:52