Issue
I have a Flask application that is running behind an NGINX reverse proxy. In one of my functions I need to construct a URL to a different service and I wish to match the HTTP scheme to whatever the NGINX entry scheme is. So if NGINX is reverse proxying an https request, I'd like to generate a url like https://my_other_service
. But if NGINX reverse proxies an http
I'd like it to be http://my_other_service
.
The flask.url_for
function is able to automatically determine the proxy scheme when I use it for endpoints in the same app so I figure this must be possible, but in my case the url I'm generating is not an endpoint in the current Flask app.
How can I determine the proxy scheme inside a flask app?
Solution
As described on this question, you can directly tell url_for
to use a specific scheme when generating a URL:
url_for('secure_thingy',
_external=True,
_scheme='https',
viewarg1=1, ...)
The problem, of course, is that you don't necessarily know whether the URL should be https or not. If it's running behind Nginx in production, it must be https. If it's running on localhost for local development, perhaps https wouldn't work.
One solution would be to just have a configuration setting for your app on what scheme to use. In your development environment, it would be set to http. In your production environment, you'd use https. That's what I would do.
An alternative is to tell Nginx to pass along a special header which you could then use to alter the scheme.
There are instructions on adding headers on the Nginx site, so here's an example:
location /some/path/ {
proxy_set_header X-Force-Https "yes";
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8000;
}
Then in your Flask code, only pass _scheme='https'
to url_for
if request.headers.get('X-Force-Https', None) == 'yes'
.
That's a more automatic solution, but will require you to modify your production web server environment.
Answered By - Ken Kinder
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.