Now that we can have users register and log in, we're also allowing them to log out. It makes a little sense to not let users log out, unless they are logged in!
You may also find you want to protect various pages, like maybe an admin page, or maybe you have subscriber content or otherwise protected or paywal content.
You can use wrapper functions for this. People tend to shy away from wrapper functions and decorators, because they can be confusing. But, look at you, you've been using them this whole time! Flask uses them for the URL routing. Let's show how we can make our own! It's actually pretty simple!
First, we add a login_required function to our
def login_required(f): @wraps(f) def wrap(*args, **kwargs): if 'logged_in' in session: return f(*args, **kwargs) else: flash("You need to login first") return redirect(url_for('login_page')) return wrap
Here, we define the function, where the parameter is f, which is convention for the fact that it wraps a function. Then, we define the wrapper.
Our wrapper here is simple, it just simply checks if the user has a "logged_in" in their session. If so, great. If not, they get a flash message and a redirect to the login page.
Now that we have the wrapper function, we're ready to apply it to whatever we want to have a login required for. For example, we can apply it to our logout page, like so:
@app.route("/logout/") @login_required def logout(): session.clear() flash("You have been logged out!") gc.collect() return redirect(url_for('dashboard'))
Simple enough, underneath the app.route wrapper, we also add another wrapper, which is the login_required wrapper. Now, in order to even get to the logout function, a user must first attempt to access the URL in the top wrapper, then they also need to satisfy the conditions of the next wrapper, and then they can finally reach the logout() function!
Pretty neat! What's more is that we can actually use this sort of dynamic treatment of our users in our templates too! We'll head there next.