Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask redirect(url_for) error with gunricorn + nginx

I am having a problem with the redirect(url_for) function in my flask app.

Any redirect(url_for("index")) line redirects the application from domain.com/app to ip-addr/app, where the ip-addr is my own client machines ip, not the server's.

This has gotten me very confused, and I don't know where exactly the issue occurs, as it only happens on the server and not on any local testing.

Details:

I am using the reverse proxy setup found here http://flask.pocoo.org/snippets/35/. My nginx config is setup like so

location /app {
                proxy_set_header X-Script-Name /app;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-Host $proxy_add_x_forwarded_for;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Scheme $scheme;
                proxy_connect_timeout 60;
                proxy_read_timeout 60;
                proxy_pass http://localhost:8000/;
        }

I have gunicorn running my flask app as a upstart task. Any hints?

EDIT:

So I dug around a bit and found that the this git report had similar issues, https://github.com/omab/django-social-auth/issues/157.

Nginx - Gunicorn serving to Nginx via localhost (127.0.0.1:1234). Unfortunately, when I authenticate with social platforms, the redirect URL social-auth is sending them to is 127.0.0.1:1234/twitter/complete, which obviously can't be resolved by the client's browser.

It seems my Flask app is not getting the memo to update its redirect routes.

like image 630
N. Ma Avatar asked Mar 10 '14 21:03

N. Ma


Video Answer


2 Answers

I found a solution. I had to use redirect(url_for(location, _external=True)) for all my redirects.

It seems url_for(x, _external=True) will take all variables in my nginx proxy_set_header to construct the url, while the url_for(x) is not doing that.

This works for both server and local development.

like image 157
N. Ma Avatar answered Oct 14 '22 13:10

N. Ma


Adding include proxy_params fixed it for me.

location / {
    proxy_pass http://...;
    include proxy_params;
}
like image 21
Ph3n0x Avatar answered Oct 14 '22 15:10

Ph3n0x