21

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.

steve
  • 2,488
  • 5
  • 26
  • 39
  • Have you tried writing a modified router? – ferrix Dec 08 '15 at 19:51
  • Is simple `login_required` check always going to be enough for you? I always end up needing different levels of permissions for different users, so I decorate everything with `require_privilege('privilege name')`. I ask becuase if you decide to go that way, then there is really no way other than decorating every route (they require different permissions). – zvone Dec 08 '15 at 19:52
  • @ferrix No, I haven't heard of that but I will check it out. zvone No we don't have different permissions/roles. Every user has the same permissions. – steve Dec 08 '15 at 19:54

1 Answers1

28

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

Community
  • 1
  • 1
Tommi Komulainen
  • 2,830
  • 1
  • 19
  • 16
  • 1
    Thanks for this and the link to the other post. ``app.view_functions`` is the secret sauce I was looking for. So long as there is a reference to the functions the urls map to those functions can be decorated. – steve Dec 08 '15 at 20:15
  • while I like that this answer shows how to make a login-requirement the default, I am a bit confused about its usage here: Shouldn't one be able to have separate blueprints for routes which require logins and such that don't, and modify the the blueprints' `::before_request` in that way? – mzoll Apr 16 '20 at 14:12
  • The use case here was with regards to a legacy app with no blueprints. All routes were defined in one file and their were hundreds of them and every one of them required authentication. – steve Jan 21 '21 at 01:09