Search code examples
pythonflaskflask-loginlogin-required

Flask: Decorate every route at once?


I have @login_required decorator that decorates a controller action. However my app is very large and has tons of routes in many different controller files. Going one by one to decorate each route seems error prone (I could easily miss one) and time consuming.

Is there a way to decorate all routes at once across the entire app?

I am moving authentication from the web server (apache) into the application level which is why I have this problem.


Solution

  • You could go the opposite way and use before_request decorator to require login by default, and use a custom decorator to tag routes that do not require login, for example:

    _insecure_views = []
    
    @my_blueprint.before_request
    def require_login():
        if request.endpoint in _insecure_views:
            return
        # check for login here
    
    def login_not_required(fn):
        '''decorator to disable user authentication'''
        endpoint = ".".join([some_blueprint.name, fn.func_name])
        _insecure_views.append(endpoint)
        return fn
    
    @some_blueprint.route('/')
    @login_not_required
    def index():
        pass
    

    You could probably wrap that into a derived blueprint/Flask class of its own.

    Edit: basically Best way to make Flask-Login's login_required the default