最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Docker container name remains recognized hostserver name when using ProxyFix for Flask behind Nginx - Stack Overflow

programmeradmin1浏览0评论

I have Nginx running in a docker container on the same network as my Flask app. I set up a reverse proxy in Nginx for my Flask app (running on gunicorn), and then setup ProxyFix to reset the Flask routes to be corrected when using functions like url_for().

The problem I am having is that I use the docker container name in my proxy_pass in Nginx, and ProxyFix doesn't seem to reset it to the real origin of the request being passed. The X-Forwarded-Proto and X-Forwarded-Prefix took, so I know ProxyFix is at least partially working.

Nginx setup. api-service is the docker container name of the flask application. This conf file has been reduced to potentially relevant items for brevity:

http {
    upstream api-service {
        server api-service:5010;
    }

    # Redirect HTTP to HTTPS
    server {
        listen 80;
        listen [::]:80;

        server_name domain1 domain2;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        listen [::]:443 ssl;

        http2 on;

        server_name domain1;

        location /api/ {
            # Dynamically set the CORS origin based on the incoming request
            set $cors_origin "";

            if ($http_origin ~* (http://localhost:4025|)) {
                set $cors_origin $http_origin;
            }

            # Add basic CORS headers for all requests
            add_header 'Access-Control-Allow-Origin' $cors_origin always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Accept, Content-Type, Authorization' always;

            # Handle CORS preflight (OPTIONS) requests
            if ($request_method = OPTIONS) {
                add_header 'Access-Control-Max-Age' 1728000;
                return 204;
            }

            # Handle other requests
            if ($request_method != OPTIONS) {
                add_header 'Access-Control-Allow-Credentials' 'true' always;
            }

            # Proxy to the API service
            proxy_pass http://api-service/;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $cors_origin;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Prefix /api;
            proxy_redirect off;
            proxy_connect_timeout 500s;
            proxy_send_timeout 500s;
            proxy_read_timeout 500s;
        }
    }
}

Flask:

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_host=1, x_proto=1, x_prefix=1)

What I'm ultimately trying to do is use url_for() to create the redirect_uri for Google OAuth:

authorization_url = client.prepare_request_uri(
   provider_data["authorize_url"],
   redirect_uri=url_for(
      "authorize.oauth2_callback", provider=provider, _external=True
   ),
   scope=provider_data["scopes"],
)

Right now, I am getting a redirect_uri like this and Google rejects it: https://api-service/api/authorize/callback/

Before I implemented ProxyFix it was creating a URL like this: http://api-service/authorize/callback which is why I know ProxyFix is at least partially doing its job.

My one thought is that maybe $cors_origin in my Nginx is not being set at the if statement and remains empty "" and that somehow causes the proxy_set_header X-Forwarded-Host $cors_origin to fallback to the docker container name? When I look at the request headers in the browser I see the proper origin, referrer, and host listed though (/ or domain1).

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论