multidomain configuration for flask application - python

I need configure flask application to handle requests with any host in HTTP header
If some fqdn is specified in SERVER_NAME I have 404 error if request goes with any other domain.
How should be defined SERVER_NAME in configuration?
How can be requested/routed/blueprint-ed HTTP hostname?

Use app.run(host='0.0.0.0') if you want flask to accept any host name.

To allow any domain name just remove 'SERVER_NAME' from application config

Related

How to capture client ip of web application in flask? [duplicate]

This question already has answers here:
What is going on when I set app.wsgi_app = ProxyFix(app.wsgi_app) when running a Flask app on gunicorn?
(2 answers)
X-Forwarded-Proto and Flask
(1 answer)
Closed 2 years ago.
I am trying to capture client ip in logs and getting correct ip on development server but after deployment on sit server, getting wrong ip by default (10.46.0.0). Please someone suggest, what else can be used in flask python? Thanks in advance.
Code:-
Import request
Ip = request.environ['REMOTE_ADDR']
The IP address you retrieve is part of the CIDR block 10.0.0.0/8 and reserved for private networks. This tells me that your application deployed behind a reverse proxy which performs requests to your application on the original users' behalves. A reverse proxy would typically inform the upstream service (your application) about the originating IP address by adding the header X-Forwarded-For to the proxied request. This depends on the configuration of the reverse proxy, so you should contact the people in charge of the deployment server about its configuration.
It seems like you got the address from a Reverse Proxy. The original client IP may be forwarded as part of the proxy chain.
This worked for me.
client_ip = request.headers.get(
'X-Forwarded-For',
request.headers.get('Client-Ip',
request.remote_addr))
There is a difference between WSGI and CGI.
WSGI: request.headers
CGI: request.environ

Flask SERVER_NAME setting best pratices

Since my app has background tasks, I use the Flask context. For the context to work, the Flask setting SERVER_NAME should be set.
When the SERVER_NAME is set the incoming requests are checked to match this value or the route isn't found. When placing an nginx (or other webserver in front), the SERVER_NAME should also include the port and the reverse proxy should handle the rewrite stuff, hiding the port number from the outside world (which it does).
For session cookies to work in modern browsers, the URL name passed by the proxy should be the same as the SERVER_NAME, otherwise the browser refuses to send the cookies. This can be solved by adding the official hostname in the /etc/hosts and setting it to 127.0.0.1.
There is one thing that I haven't figured out yet and it is the URL in the background tasks. url_for() is used with the _external option to generate URLs in the mail it sends out. But that URL includes the port, which is different from the 443 port used by my nginx instance.
Removing the port from the SERVER_NAME makes the stuff described in the first paragraph fail.
So what are my best options for handling the url_for in the mail. Create a separate config setting? Create my own url_for?
You should use url_for(location, _external=True)
or include proxy_params if you use nginx.

How to pass correct client ip from nginx running in one container to python-flask app running 2nd container? [duplicate]

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!
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
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']

After configure the nginx, I can't see the index page

This is my first time to use nginx
I wrote a simple python/tornado code as the following, when I used python server.py I could see the index.html page.
from tornado.options import define, options
from db import MongoImpl
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render("./pages/index.html")
app = tornado.web.Application([(r'/', IndexHandler)],
debug=True)
app.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
Then I started to configure the nginx.conf, I added the following to default nginx.conf:
http {
server{
listen 8000;
root /home/ubuntu/work/mytornado/pages;
index index.html index.htm;
}
then i nginx -s reload
however, when I used http://myipaddress, i only see the nginx welcome page, not my index html....
Is there anything wrong ?
You cannot run both nginx and your tornado server on port 8000. You need to give them each a different port, and configure nginx to proxy to tornado with a proxy_pass directive (this will replace the root directive you have here which serves pages from the filesystem. If you want nginx to serve some files from the filesystem and some from tornado then you'll need to use two location blocks).
A complete nginx configuration for use with tornado can be found in the docs: http://www.tornadoweb.org/en/stable/guide/running.html#running-behind-a-load-balancer

Specify port for url_for

How can I specify the port used for the Flask url_for method? Or, can I configure Flask to use whatever port it is running on for url_for? My issue is that I'm running a server on port 8080 but url_for does not add this port to any URLs generated, so any generated URLs use port 80 and do not resolve.
It seems the only way to specify a port in url_for is to use the _external=True argument like so:
url_for('handle_contact_form', _external=True)
This generates a URL like http://localhost:5000/contact-us. Unfortunately a :5000/contact-us isn't a valid relative URL. So without using a full, external URL, the port cannot be specified.

Categories

Resources