Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 591
steve Avatar asked Dec 08 '15 19:12

steve


People also ask

Can you use multiple decorators to route URLs to a function in Flask?

In some cases you can reuse a Flask route function for multiple URLs. Or you want the same page/response available via multiple URLs. In that case you can add a second route to the function by stacking a second route decorator to the function.

Do flasks use decorators?

Because each view in Flask is a function, decorators can be used to inject additional functionality to one or more functions. The route() decorator is the one you probably used already. But there are use cases for implementing your own decorator.

How do Flask applications use function decorators?

In the case of Flask's decorators, they are checking to see if an incoming request matches the route you've specified. If it does, then it executes the function. Otherwise, it checks the next route.

How do I protect my route in Flask?

On any endpoint that you want to protect (i.e. make sure users are logged in before accessing it), just place the decorator above the endpoint definition. Just make sure the decorator is under the @app. route... line!


1 Answers

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

like image 149
Tommi Komulainen Avatar answered Oct 08 '22 18:10

Tommi Komulainen