David Yang
David Yang

Reputation: 2141

Flask IIS Webapp Attempting to Get User IP Address

I am attempting to deploy a Flask webapp onto IIS. First, I used standard suggestions (Flask, IIS, wfastcgi). This method allowed me to correctly see the IPs of users using ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)

For various reasons detailed here: wfastcgi 500 error in flask app when trying to plot , I was encouraged to stop using wfastcgi. So I followed instructions to configure Flask on IIS using httpplatformhandler. This is my config file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" requireAccess="Script" />
        </handlers>
        <httpPlatform stdoutLogEnabled="true" stdoutLogFile=".\logs\python.log" startupTimeLimit="20" processPath="C:\ProgramData\Anaconda3\python.exe" arguments="-m waitress --port %HTTP_PLATFORM_PORT% wsgi:application">
          <environmentVariables>
              <environmentVariable name="FLASK_APP" value="C:\dcm_webapp\main.py" />
          </environmentVariables>
        </httpPlatform>
        <tracing>
            <traceFailedRequests>
                <add path="*">
                    <traceAreas>
                        <add provider="ASP" verbosity="Verbose" />
                        <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
                        <add provider="ISAPI Extension" verbosity="Verbose" />
                        <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI,WebSocket" verbosity="Verbose" />
                    </traceAreas>
                    <failureDefinitions statusCodes="400-500" />
                </add>
            </traceFailedRequests>
        </tracing>
    </system.webServer>
</configuration>

Fortunately, this configuration solved the problem of random python functions causing 500s on IIS, but now when I try to get the user's IP, I always just get localhost back.

Is there a way to configure this so that using request.environ.get('HTTP_X_REAL_IP', request.remote.addr) gets me the user's IP instead of localhost?

Thanks :)

Upvotes: 1

Views: 240

Answers (1)

Jasper
Jasper

Reputation: 484

With some trial and error I got this to work in a Python Flask app running in httpplatformhandler on IIS:

Method:

def get_remote_addr(self):
    if "X-Forwarded-For" in request.headers:
        remote_addr = request.headers["X-Forwarded-For"]
        if ":" in remote_addr:
            remote_addr = remote_addr.split(":")[0]
    else:
        remote_addr = request.environ.get("HTTP_X_REAL_IP", request.remote_addr)
    return remote_addr

Web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" requireAccess="Script" />
        </handlers>
        <httpPlatform stdoutLogEnabled="false" stdoutLogFile=".\python.log" startupTimeLimit="20" processPath="c:\Python\python.exe" arguments="-m waitress --threads 8 --trusted-proxy 127.0.0.1 --trusted-proxy-headers forwarded --port %HTTP_PLATFORM_PORT% wsgi:application">
        </httpPlatform>
    </system.webServer>
</configuration>

Upvotes: 1

Related Questions