Difference between revisions of "Flask Session Management"
Jump to navigation
Jump to search
PeterHarding (talk | contribs) (Created page with " * https://stormpath.com/blog/part-two-solving-flask-authentication-problem/") |
PeterHarding (talk | contribs) |
||
(9 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Also see - [[Flask Stuff]] | |||
=Various References= | |||
* https://stormpath.com/blog/part-two-solving-flask-authentication-problem/ | * https://stormpath.com/blog/part-two-solving-flask-authentication-problem/ | ||
* http://flask.pocoo.org/docs/appcontext/ | |||
* http://runnable.com/Uhf58hcCo9RSAACs/using-sessions-in-flask-for-python | |||
* http://stackoverflow.com/questions/6972999/flask-user-authentication | |||
* https://github.com/mbr/flask-kvsession | |||
* https://pythonhosted.org/Flask-Security/ | |||
* https://www.openshift.com/blogs/use-flask-login-to-add-user-authentication-to-your-python-application | |||
==OpenShift== | |||
* https://www.openshift.com/blogs/use-flask-login-to-add-user-authentication-to-your-python-application | |||
=Server Side Session with Redis= | |||
* http://flask.pocoo.org/snippets/75/ | |||
<pre> | |||
import pickle | |||
from datetime import timedelta | |||
from uuid import uuid4 | |||
from redis import Redis | |||
from werkzeug.datastructures import CallbackDict | |||
from flask.sessions import SessionInterface, SessionMixin | |||
class RedisSession(CallbackDict, SessionMixin): | |||
def __init__(self, initial=None, sid=None, new=False): | |||
def on_update(self): | |||
self.modified = True | |||
CallbackDict.__init__(self, initial, on_update) | |||
self.sid = sid | |||
self.new = new | |||
self.modified = False | |||
class RedisSessionInterface(SessionInterface): | |||
serializer = pickle | |||
session_class = RedisSession | |||
def __init__(self, redis=None, prefix='session:'): | |||
if redis is None: | |||
redis = Redis() | |||
self.redis = redis | |||
self.prefix = prefix | |||
def generate_sid(self): | |||
return str(uuid4()) | |||
def get_redis_expiration_time(self, app, session): | |||
if session.permanent: | |||
return app.permanent_session_lifetime | |||
return timedelta(days=1) | |||
def open_session(self, app, request): | |||
sid = request.cookies.get(app.session_cookie_name) | |||
if not sid: | |||
sid = self.generate_sid() | |||
return self.session_class(sid=sid, new=True) | |||
val = self.redis.get(self.prefix + sid) | |||
if val is not None: | |||
data = self.serializer.loads(val) | |||
return self.session_class(data, sid=sid) | |||
return self.session_class(sid=sid, new=True) | |||
def save_session(self, app, session, response): | |||
domain = self.get_cookie_domain(app) | |||
if not session: | |||
self.redis.delete(self.prefix + session.sid) | |||
if session.modified: | |||
response.delete_cookie(app.session_cookie_name, | |||
domain=domain) | |||
return | |||
redis_exp = self.get_redis_expiration_time(app, session) | |||
cookie_exp = self.get_expiration_time(app, session) | |||
val = self.serializer.dumps(dict(session)) | |||
self.redis.setex(self.prefix + session.sid, val, | |||
int(redis_exp.total_seconds())) | |||
response.set_cookie(app.session_cookie_name, session.sid, | |||
expires=cookie_exp, httponly=True, | |||
domain=domain) | |||
</pre> | |||
Here is how to enable it: | |||
<pre> | |||
app = Flask(__name__) | |||
app.session_interface = RedisSessionInterface() | |||
</pre> | |||
If you get an attribute error that total_seconds is missing it means you're using a version of Python older than 2.7. In this case you can use this function as a replacement for the total_seconds method: | |||
<pre> | |||
def total_seconds(td): | |||
return td.days * 60 * 60 * 24 + td.seconds | |||
</pre> | |||
[[Category:Flask]] | |||
[[Category:Python]] |
Latest revision as of 00:38, 9 July 2014
Also see - Flask Stuff
Various References
- https://stormpath.com/blog/part-two-solving-flask-authentication-problem/
- http://flask.pocoo.org/docs/appcontext/
- http://runnable.com/Uhf58hcCo9RSAACs/using-sessions-in-flask-for-python
- http://stackoverflow.com/questions/6972999/flask-user-authentication
- https://github.com/mbr/flask-kvsession
- https://pythonhosted.org/Flask-Security/
- https://www.openshift.com/blogs/use-flask-login-to-add-user-authentication-to-your-python-application
OpenShift
Server Side Session with Redis
import pickle from datetime import timedelta from uuid import uuid4 from redis import Redis from werkzeug.datastructures import CallbackDict from flask.sessions import SessionInterface, SessionMixin class RedisSession(CallbackDict, SessionMixin): def __init__(self, initial=None, sid=None, new=False): def on_update(self): self.modified = True CallbackDict.__init__(self, initial, on_update) self.sid = sid self.new = new self.modified = False class RedisSessionInterface(SessionInterface): serializer = pickle session_class = RedisSession def __init__(self, redis=None, prefix='session:'): if redis is None: redis = Redis() self.redis = redis self.prefix = prefix def generate_sid(self): return str(uuid4()) def get_redis_expiration_time(self, app, session): if session.permanent: return app.permanent_session_lifetime return timedelta(days=1) def open_session(self, app, request): sid = request.cookies.get(app.session_cookie_name) if not sid: sid = self.generate_sid() return self.session_class(sid=sid, new=True) val = self.redis.get(self.prefix + sid) if val is not None: data = self.serializer.loads(val) return self.session_class(data, sid=sid) return self.session_class(sid=sid, new=True) def save_session(self, app, session, response): domain = self.get_cookie_domain(app) if not session: self.redis.delete(self.prefix + session.sid) if session.modified: response.delete_cookie(app.session_cookie_name, domain=domain) return redis_exp = self.get_redis_expiration_time(app, session) cookie_exp = self.get_expiration_time(app, session) val = self.serializer.dumps(dict(session)) self.redis.setex(self.prefix + session.sid, val, int(redis_exp.total_seconds())) response.set_cookie(app.session_cookie_name, session.sid, expires=cookie_exp, httponly=True, domain=domain)
Here is how to enable it:
app = Flask(__name__) app.session_interface = RedisSessionInterface()
If you get an attribute error that total_seconds is missing it means you're using a version of Python older than 2.7. In this case you can use this function as a replacement for the total_seconds method:
def total_seconds(td): return td.days * 60 * 60 * 24 + td.seconds