Last active
April 8, 2017 00:54
-
-
Save brennv/823ea069217b2d4b53d33b83d7bb0d71 to your computer and use it in GitHub Desktop.
Session Interface example for url-based session max_age flip-flopping in Flask
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from werkzeug.datastructures import CallbackDict | |
from flask.sessions import SessionInterface, SessionMixin | |
from itsdangerous import URLSafeTimedSerializer, BadSignature | |
from datetime import datetime, timedelta | |
class ItsdangerousSession(CallbackDict, SessionMixin): | |
def __init__(self, initial=None): | |
def on_update(self): | |
self.modified = True | |
CallbackDict.__init__(self, initial, on_update) | |
self.modified = False | |
class ItsdangerousSessionInterface(SessionInterface): | |
salt = 'cookie-session' | |
session_class = ItsdangerousSession | |
def get_serializer(self, app): | |
if not app.secret_key: | |
return None | |
return URLSafeTimedSerializer(app.secret_key, | |
salt=self.salt) | |
def open_session(self, app, request): | |
s = self.get_serializer(app) | |
if s is None: | |
return None | |
val = request.cookies.get(app.session_cookie_name) | |
if not val: | |
return self.session_class() | |
# max_age = app.permanent_session_lifetime.total_seconds() | |
if request.endpoint == 'admin': | |
max_age = 10 | |
else: | |
max_age = 10000 | |
print('max_age', max_age) | |
try: | |
data = s.loads(val, max_age=max_age) | |
return self.session_class(data) | |
except BadSignature: | |
self.session_class().clear() # added this | |
print('session cleared') | |
return self.session_class() | |
def save_session(self, app, session, response): | |
domain = self.get_cookie_domain(app) | |
if not session: | |
if session.modified: | |
response.delete_cookie(app.session_cookie_name, | |
domain=domain) | |
return | |
expires = self.get_expiration_time(app, session) | |
val = self.get_serializer(app).dumps(dict(session)) | |
response.set_cookie(app.session_cookie_name, val, | |
expires=expires, httponly=True, | |
domain=domain) | |
from flask import Flask, session, redirect, url_for, request | |
import random | |
app = Flask(__name__) | |
app.secret_key = 'secrets' | |
app.session_interface = ItsdangerousSessionInterface() | |
def check_db(arg): | |
# TODO add sqlite db | |
return arg | |
@app.before_request | |
def before(): | |
session.permanent = True | |
print(session) | |
@app.route('/home') | |
def home(): | |
return 'home' | |
@app.route('/login', methods=['GET', 'POST']) | |
def login(): | |
if check_db(True): # authentincate user | |
session['user_data'] = random.randint(100,999) | |
return 'logged in' | |
@app.route('/admin') | |
def admin(): | |
if check_db(True): # check for user role | |
return 'admin' | |
else: | |
redirect(url_for('home')) | |
@app.route('/logout') | |
def logout(): | |
session.clear() | |
return 'logged out' | |
if __name__ == '__main__': | |
app.run(debug=True, threaded=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment