📖 Scenario: You are building a simple Flask web app that has some pages only accessible to logged-in users.To protect these pages, you want to create a login_required decorator that checks if a user is logged in before allowing access.
🎯 Goal: Create a login_required decorator in Flask that redirects users to the login page if they are not logged in.Use this decorator on a protected route to ensure only logged-in users can see it.
📋 What You'll Learn
Create a Flask app with a route /dashboard that requires login
Create a login_required decorator that checks if session['logged_in'] is true
If not logged in, redirect to /login
Use the decorator on the /dashboard route
💡 Why This Matters
🌍 Real World
Web apps often need to restrict access to certain pages only to logged-in users. This decorator pattern helps keep code clean and reusable.
💼 Career
Understanding how to protect routes and manage user sessions is a key skill for backend web developers working with Flask or similar frameworks.
Progress0 / 4 steps
1
Set up Flask app and session
Import Flask and create an app instance called app. Set a secret key 'secret123' for sessions.
Flask
Hint
Remember to import Flask and create the app variable.
2
Create the login_required decorator
Define a function called login_required that takes a function f as argument. Inside, define a wrapper function decorated_function that checks if session.get('logged_in') is true. If not, return redirect(url_for('login')). Otherwise, return f(). Use functools.wraps(f) to preserve function metadata. Return decorated_function from login_required.
Flask
Hint
Use functools.wraps and check session.get('logged_in').
3
Create the protected dashboard route
Create a route /dashboard using @app.route('/dashboard'). Define a function dashboard decorated with @login_required. Return the string 'Welcome to your dashboard!' from this function.
Flask
Hint
Use @app.route('/dashboard') and decorate with @login_required.
4
Add a simple login route to set session
Create a route /login using @app.route('/login'). Define a function login that sets session['logged_in'] = True and returns the string 'You are now logged in.'.
Flask
Hint
Create a simple login route that sets session['logged_in'] to True.
Practice
(1/5)
1. What is the main purpose of the @login_required decorator in Flask?
easy
A. To automatically log out users after a timeout
B. To restrict access to a view so only logged-in users can see it
C. To register a new user in the database
D. To display a welcome message on the homepage
Solution
Step 1: Understand the role of @login_required
This decorator is used to protect routes so only authenticated users can access them.
Step 2: Identify what it does in Flask-Login
If a user is not logged in, it redirects them to the login page instead of showing the protected content.
Final Answer:
To restrict access to a view so only logged-in users can see it -> Option B
Quick Check:
Access control = Restrict to logged-in users [OK]
Hint: Think: Who should see this page? Only logged-in users! [OK]
Common Mistakes:
Confusing login_required with user registration
Thinking it logs out users automatically
Assuming it shows messages instead of restricting access
2. Which of the following is the correct way to use the @login_required decorator in a Flask view function?
easy
A. def @login_required my_view(): pass
B. def my_view() @login_required: pass
C. @login_required
def my_view(): pass
D. my_view = login_required(def my_view()): pass
Solution
Step 1: Recall Python decorator syntax
Decorators are placed on the line above the function with an @ symbol, then the function is defined normally.
Step 2: Match correct syntax for @login_required
@login_required
def my_view(): pass correctly places @login_required above the function definition.
Final Answer:
@login_required\ndef my_view(): pass -> Option C
Quick Check:
Decorator above function = @login_required
def my_view(): pass [OK]
Hint: Decorator always goes on the line before the function [OK]
Common Mistakes:
Placing @login_required inside the function signature
Trying to use @login_required after function definition
Using invalid Python syntax for decorators
3. Given this Flask route with @login_required:
@app.route('/dashboard')
@login_required
def dashboard():
return 'Welcome to your dashboard'
What happens if a user who is NOT logged in tries to visit /dashboard?
medium
A. They are redirected to the login page
B. They get a 404 Not Found error
C. They see the message 'Welcome to your dashboard'
D. The server crashes with an error
Solution
Step 1: Understand @login_required behavior
This decorator checks if the user is authenticated before allowing access.
Step 2: What happens if user is not logged in?
The decorator redirects unauthenticated users to the login page automatically.
Final Answer:
They are redirected to the login page -> Option A
Quick Check:
Not logged in = redirect to login [OK]
Hint: Not logged in? Redirect to login page! [OK]
Common Mistakes:
Thinking the page content shows anyway
Assuming a 404 error occurs
Believing the server crashes
4. Consider this Flask code snippet:
from flask_login import login_required
@app.route('/profile')
def profile():
return 'User Profile'
Why will this code NOT restrict access to logged-in users?
medium
A. Because the function name must be login_required
B. Because login_required must be imported from flask, not flask_login
C. Because the route decorator must come after @login_required
D. Because @login_required is missing above the profile function
Solution
Step 1: Check if @login_required is applied
The function profile lacks the @login_required decorator above it.
Step 2: Understand decorator order and import
Import from flask_login is correct, and route decorator order is flexible, but missing @login_required means no access restriction.
Final Answer:
Because @login_required is missing above the profile function -> Option D
Quick Check:
Missing decorator = no restriction [OK]
Hint: Decorator must be above function to restrict access [OK]
Common Mistakes:
Thinking import location causes the issue
Believing decorator order is wrong
Assuming function name affects access control
5. You want to protect multiple routes in your Flask app so only logged-in users can access them. Which approach correctly protects these routes without repeating the @login_required decorator on each function?
A) Use a custom decorator that wraps @login_required and apply it to each function
B) Apply @login_required once on the Flask app object
C) Add @login_required only to the first route function and it applies to all others
D) Use Flask's before_request to check login status and redirect if needed
hard
A. Use Flask's before_request to check login status and redirect if needed
B. Apply @login_required once on the Flask app object
C. Add @login_required only to the first route function and it applies to all others
D. Use a custom decorator that wraps @login_required and apply it to each function
Solution
Step 1: Understand how to protect multiple routes efficiently
Applying @login_required individually works but is repetitive.
Step 2: Use before_request to check login once for all routes
Flask's before_request runs before every request, so you can check if the user is logged in and redirect if not, protecting multiple routes centrally.
Step 3: Evaluate other options
Use a custom decorator that wraps @login_required and apply it to each function still requires decorating each function. Apply @login_required once on the Flask app object is invalid because @login_required is not applied to the app object. Add @login_required only to the first route function and it applies to all others is incorrect because decorators do not cascade to other functions.
Final Answer:
Use Flask's before_request to check login status and redirect if needed -> Option A
Quick Check:
Central login check = before_request [OK]
Hint: Use before_request for one check on all routes [OK]
Common Mistakes:
Thinking one decorator on app protects all routes
Assuming decorators cascade automatically
Not knowing about before_request hook
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.