Last active
June 30, 2019 15:48
-
-
Save andybp85/7cef5007089795f9e521f253fcf27eff to your computer and use it in GitHub Desktop.
subclass of flask-security to demonstrate adding routes to security blueprint. implements a '/check' route to check and refresh tokens.
This file contains 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 flask import request, current_app | |
from flask.json import jsonify | |
from flask.ext.security import Security, SQLAlchemyUserDatastore, current_user | |
from flask.ext.security.views import create_blueprint | |
from flask.ext.security.decorators import auth_token_required | |
from flask.ext.security.utils import url_for_security, md5 | |
from flask.ext.login import make_secure_token | |
from werkzeug.local import LocalProxy | |
from itsdangerous import SignatureExpired | |
from app.models import db | |
from app.models.users import Role, User | |
#from trepan.api import debug | |
# new favorite debugger! To use just uncomment and | |
# add debug() whereever you want to break. | |
class AppSecurity(Security): | |
''' This class is broken out to keep the logic for additional routes out of the main | |
app file. Getting the app var imported with the proper context to use the decorator | |
seems basically impossible, so in order to add routes to the security blueprint we | |
make the blueprint seperately, add what we want, and then register it. | |
''' | |
def __init__(self, app, *args, **kwargs): | |
user_datastore = SQLAlchemyUserDatastore(db, User, Role) | |
security = Security(app, user_datastore, register_blueprint=False, *args, **kwargs) | |
bp = create_blueprint(security._state,'security') | |
@bp.context_processor | |
def addStuffThatShouldBeThere(): | |
''' Use this to add whatever functions are needed for the security templates to run. | |
You'll be able to see whatever you need from the browser debugger. | |
''' | |
return { "url_for_security" : url_for_security, "security" : security} | |
@bp.route('/check', methods=['GET']) | |
@auth_token_required | |
def check_token_status(): | |
''' Path for checking and refreshing token. Tokens, while valid for 7 days, | |
will be refreshed if older than one hour. Based on | |
flask.ext.security.utils.get_token_status | |
200: new token included | |
204: token is valid | |
401: token is invalid | |
''' | |
token = request.headers.get('Authentication-Token') | |
_security = LocalProxy(lambda: current_app.extensions['security']) | |
serializer = getattr(_security, 'remember_token_serializer') | |
try: | |
data = serializer.loads(token, max_age=3600) | |
return ('', 204) | |
except SignatureExpired: | |
data = [str(current_user.id), md5(current_user.password)] | |
return jsonify({"token" : serializer.dumps(data)}) | |
app.register_blueprint(bp) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment