Flask-CrossDomain-Session is a Flask extension that simplifies the task of keeping sessions spanning multiple domains.
Simply run:
pip install Flask-CrossDomain-Session
Normal usage looks something like this:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_crossdomain_session import CrossDomainSession, make_session_class, make_session_instance_class
app = Flask(__name__)
app.config['CROSSDOMAIN_PRIMARY_SERVERNAME'] = 'primary.tld'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
Session = make_session_class(db, User)
SessionInstance = make_session_instance_class(db, Session)
crossdomain = CrossDomainSession(app)
crossdomain.session_instance_class = SessionInstance
@crossdomain.domain_loader
def domain_loader():
return ['primary.tld', 'secondary.tld', 'another.tld']
And add this somewhere in your Jinja2 templates: {{ flask_crossdomain_session_code() }}
You can then use flask.session
like normal, and if everything works correctly it'll have the same content
regardless of which of your domains you visit.
Option | Default | Description |
---|---|---|
CROSSDOMAIN_PRIMARY_SERVERNAME |
SERVER_NAME |
The primary domain name, other domains make AJAX calls to this one |
CROSSDOMAIN_PATH |
/crossdomain |
The path of the page to which AJAX calls are made |
All sessions are stored in a database (convenience functions to use SQLAlchemy are included, but you should be able
to use any other by manually inheriting from SessionMixin
and SessionInstanceMixin
). When loading a page that
contains a cookie with a session token a session matching that token is loaded from the database. If no such cookie
is present, or if no matching session can be found, a new session is created and its token returned in a new cookie.
When loading a page that is not the primary a bit of JavaScript is injected into the page. It first checks in
localStorage
if a recent AJAX check has been made, and if not an AJAX request is sent. That AJAX request has an
action called check
, the current session token and a boolean indicating if the session is new (was created in the
most recent request). It is sent to the primary domain, that way any session cookie already set on the primary domain
is also included in the request. The server then does one of these things:
- If both the token of the current domain (as sent in the AJAX body) and of the primary domain (as included in the
cookies) are equal the server just returns
use_current
, nothing then needs to be done by the client. - If the session on the primary domain didn't already exist it is replaced by the one that the token from the current
domain (as sent in the AJAX body) represents, and
use_current
is returned. - If a session on the primary domain already existed and the session on the current domain was new we instead
return
replace
with the token of the primary domains session. The JavaScript then sends a new AJAX request to the current domain with the actionreplace
and the token of the primary domains session, which replaces the cookie of the current domain. Once that is done the page is reloaded to reflect the new session. - If neither session is new we have run into a bit of a problem. Usually that shouldn't happen, but could theoretically in case of broken connections and other issues. In that case we use the session that has a user set (that has been used to login), and if both have a user set we use the primary session.
The primary domain used is determined using the CONSENT_PRIMARY_SERVERNAME
configuration option,
which by default is set to SERVER_NAME
.
Since it is needed for the AJAX requests this extension also sets the CORS headers (Access-Control-*
) for the
given domains.
- Get the code:
git clone https://github.com/02JanDal/Flask-CrossDomain-Session.git
- Do your changes
- Test the result:
tox -e py