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

后端 未结 4 990
别那么骄傲
别那么骄傲 2020-12-12 21:00

Like this question: Best way to make Django's login_required the default

I\'m using Flask-Login\'s login_required decorator now. Is there anyway to

相关标签:
4条回答
  • 2020-12-12 21:30

    I did this in my instruments project. I use the before_request decorator:

    @app.before_request
    def check_valid_login():
        login_valid = 'user' in session # or whatever you use to check valid login
    
        if (request.endpoint and 
            'static' not in request.endpoint and 
            not login_valid and 
            not getattr(app.view_functions[request.endpoint], 'is_public', False) ) :
            return render_template('login.html', next=request.endpoint)
    

    and I then created an is_public() decorator for the few places that would need to be accessible without login:

    def public_endpoint(function):
        function.is_public = True
        return function
    
    0 讨论(0)
  • 2020-12-12 21:33

    This is a follow up ( bit more pythonic but thats debatable ) to @MalphasWats already great answer.

    Also includes an important security fix suggested by @nonagon.

    Explanation of the vulnerability with 'static' in request.endpoint:

    Imagine that there is route which can be user defiened in some way, like a profile link for example.

    If the user sets his name lets say Static Joe, then:

    "Static Joe" --slugifys--> /usr/profiles/static_joe.

    This way making this route public. This is just asking for trouble.


    Here is the route guard function which is appened before every request handling:

    @app.before_request
    def check_route_access():
        if any([request.endpoint.startswith('static/'),
                current_user.is_authenticated,  # From Flask-Login
                getattr(app.view_functions[request.endpoint],'is_public',False)]):
            return  # Access granted
        else:
            return redirect(url_for('users.login_page'))
    

    ( Flask-Login is an excellent module and makes session handling a breeze )

    And here is the decorator ( @public_route ) which you can use to allow access to special pages that need public access by default. (register page, login page):

    def public_route(decorated_function):
        decorated_function.is_public = True
        return decorated_function
    
    0 讨论(0)
  • 2020-12-12 21:38

    If you are using blueprints and need to protect an entire blueprint with a login, you can make the entire before_request to require login.

    This is what I use for my CMS blueprint:

    @cms.before_request
    @login_required
    def before_request():
        if g.user.role != ROLE_ADMIN:
            abort(401)
    

    If you need only to check if the user is logged in (and not if the user has privileges) you can simply pass the function

    0 讨论(0)
  • 2020-12-12 21:45

    I had to secure a REST API and I have solved finally like this:

    @app.before_request
    @auth.login_required
    def login_required_for_all_request():    
        pass  
    

    (Actually I used also the connexion framework so I had to use: @app.app.before_request )

    0 讨论(0)
提交回复
热议问题