Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure a single flask application to handle multiple domains?

Tags:

python

flask

Currently, my flask application (that uses sessions) does the following to handle ONE domain:

app.config.from_object(settings)

and in the settings object:

SESSION_COOKIE_DOMAIN = ".first.com"

What I'd like to do now is to dynamically set the session cookie domain to handle, for example, requests from www.first.com and www.second.com. Please note that I'm talking about domains but not subdomains. Thank you.

like image 470
dragon-fly999 Avatar asked Nov 04 '14 15:11

dragon-fly999


People also ask

Can Flask handle multiple requests at the same time?

Flask applications are deployed on a web server, either the built-in server for development and testing or a suitable server (gunicorn, nginx etc.) for production. By default, the server can handle multiple client requests without the programmer having to do anything special in the application.

How do I run a Flask in a separate thread?

To start a Python Flask application in separate thread, we set the use_reloader to False when we call app. run . And then we create a Thread instance with the Flask app by setting the function that calls app. run as the value of the target argument.

Does Flask use multiple processes?

Multitasking is the ability to execute multiple tasks or processes (almost) at the same time. Modern web servers like Flask, Django, and Tornado are all able to handle multiple requests simultaneously.

How many requests can Flask handle per second?

For reference, the Flask benchmarks on techempower give 25,000 requests per second.


1 Answers

Grepping SESSION_COOKIE_DOMAIN through Flask's Github repo one can see that it is used like this:

def get_cookie_domain(self, app):
    """Helpful helper method that returns the cookie domain that should
    be used for the session cookie if session cookies are used.
    """
    if app.config['SESSION_COOKIE_DOMAIN'] is not None:
        return app.config['SESSION_COOKIE_DOMAIN']
    if app.config['SERVER_NAME'] is not None:
        # chop of the port which is usually not supported by browsers
        rv = '.' + app.config['SERVER_NAME'].rsplit(':', 1)[0]

        # Google chrome does not like cookies set to .localhost, so
        # we just go with no domain then.  Flask documents anyways that
        # cross domain cookies need a fully qualified domain name
        if rv == '.localhost':
            rv = None

        # If we infer the cookie domain from the server name we need
        # to check if we are in a subpath.  In that case we can't
        # set a cross domain cookie.
        if rv is not None:
            path = self.get_cookie_path(app)
            if path != '/':
                rv = rv.lstrip('.')

        return rv

Doing the same thing with get_cookie_domain( you'll see:

def save_session(self, app, session, response):
    domain = self.get_cookie_domain(app)
    path = self.get_cookie_path(app)

    ...

OK. Now we only need to find out what domain name to use. Digging through docs or code you'll see that save_session() is called in request context. So you just need to import the request object from flask module:

from flask import request

and use it inside save_session() to determine domain name for the cookies (e.g. from the Host header) like this:

def save_session(self, app, session, response):
    domain = '.' + request.headers['Host']
    path = self.get_cookie_path(app)

    # the rest of the method is intact

The only time you need to specify cookies domain is when you send them back with response object.

Also bear in mind that Host header might be absent.

To wire up the whole thing you'll need to specify your version (subclass) of SecureCookieSessionInterface:

app = Flask(__name__)
app.session_interface = MySessionInterface()

More doc links:

  • Response Object
  • Session Interface
like image 195
twil Avatar answered Oct 20 '22 00:10

twil