🏰 The Castle Gates: Flask User Authentication
Imagine your Flask app is a magical castle. Anyone can walk by and look at the outside walls. But the treasure rooms inside? Only people with the right keys can enter!
🎭 The Story of Login and Logout
Think of login and logout like checking in and out of a fancy hotel.
When you arrive (Login):
- You go to the front desk
- Show your ID (username)
- Give your secret code (password)
- Get a room key card (session)
When you leave (Logout):
- Return your key card
- The hotel forgets you were there
- You’re just a stranger again
🔑 Login Function: Opening the Door
The login_user() function is like a magic spell that says “This person is allowed in!”
from flask_login import login_user
@app.route('/login', methods=['POST'])
def login():
user = User.query.filter_by(
username=request.form['username']
).first()
if user and user.check_password(
request.form['password']
):
login_user(user)
return redirect('/dashboard')
return 'Wrong password!'
What happens when login_user(user) runs:
- 🍪 Flask creates a special cookie
- 🆔 Stores the user’s ID in the session
- ✅ Marks them as “logged in”
🚪 Logout Function: Closing the Door
The logout_user() function is like saying “Goodbye! Please forget me!”
from flask_login import logout_user
@app.route('/logout')
def logout():
logout_user()
return redirect('/')
What happens:
- 🗑️ Session gets cleared
- 🍪 Cookie becomes meaningless
- 👻 User becomes anonymous again
👤 The current_user Proxy: Who’s Knocking?
Imagine a magical mirror that always shows who’s standing at the door.
current_user is that mirror - it ALWAYS knows who’s asking!
from flask_login import current_user
@app.route('/profile')
def profile():
if current_user.is_authenticated:
return f"Hello, {current_user.username}!"
return "Hello, stranger!"
The magic of current_user:
| Property | Logged In User | Anonymous User |
|---|---|---|
.is_authenticated |
True |
False |
.is_active |
True |
False |
.is_anonymous |
False |
True |
.get_id() |
User ID | None |
🛡️ The @login_required Decorator: The Royal Guard
Picture a guard standing at the treasure room door. No key? No entry!
from flask_login import login_required
@app.route('/treasure')
@login_required
def treasure_room():
return "Welcome to the treasure!"
What happens without login:
- 🚫 Guard stops you
- 📍 Remembers where you wanted to go
- ➡️ Sends you to login page
After you login:
- Guard lets you through to treasure room!
🏰 Protecting Routes: Building Castle Walls
Not all pages need protection. Here’s how to think about it:
PUBLIC ROUTES (No guard needed)
├── / (Home page)
├── /about (About page)
└── /login (Login page)
PROTECTED ROUTES (Guard required)
├── /dashboard
├── /settings
├── /profile
└── /admin
Simple pattern:
# Public - anyone can see
@app.route('/')
def home():
return "Welcome everyone!"
# Protected - members only
@app.route('/dashboard')
@login_required
def dashboard():
return f"Hi {current_user.username}!"
👻 Anonymous Users: The Invisible Visitors
When someone visits without logging in, they’re not “nothing” - they’re an Anonymous User.
graph TD A["Visitor arrives"] --> B{Logged in?} B -->|Yes| C["current_user = Real User"] B -->|No| D["current_user = AnonymousUser"] C --> E[".is_authenticated = True"] D --> F[".is_authenticated = False"]
Anonymous users are special objects:
# You can still use current_user safely!
@app.route('/greeting')
def greet():
if current_user.is_anonymous:
return "Hello, mysterious stranger!"
return f"Hello, {current_user.username}!"
Why this matters:
- ✅ No crashes when checking
current_user - ✅ Easy to write “if logged in” code
- ✅ Clean, safe templates
🎨 Putting It All Together
Here’s the complete castle security system:
from flask import Flask, redirect, url_for
from flask_login import (
LoginManager,
login_user,
logout_user,
login_required,
current_user
)
app = Flask(__name__)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
# The front gate - anyone can enter
@app.route('/')
def home():
return "Welcome to the castle!"
# Check-in desk
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
user = User.query.filter_by(
username=request.form['username']
).first()
if user and user.check_password(
request.form['password']
):
login_user(user)
return redirect('/treasure')
return render_template('login.html')
# Check-out
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect('/')
# The treasure room - guards required!
@app.route('/treasure')
@login_required
def treasure():
return f"{current_user.username}'s treasure!"
🌟 Quick Memory Tricks
| Concept | Think Of It As… |
|---|---|
login_user() |
Giving someone a key card |
logout_user() |
Taking back the key card |
current_user |
Magic mirror showing who’s there |
@login_required |
Guard at the door |
is_authenticated |
“Do they have a valid key?” |
is_anonymous |
“Are they a stranger?” |
🎯 Remember This!
LOGIN → Give them a key 🔑
LOGOUT → Take back the key 🚪
current_user → Who has the key now? 👤
@login_required → Check for key first! 🛡️
Anonymous → No key = stranger 👻
You’ve now learned to protect your Flask castle like a pro! 🏰✨
