🏰 The Castle Gates: User Authentication in Flask
Imagine your Flask app is a magical castle. Anyone can walk up to the gates… but only trusted people should get inside. Today, you’ll become the Gatekeeper—deciding who enters and who doesn’t!
🎭 Our Story: The Castle and Its Guests
Think of your web app like a castle:
- Visitors = People who come to your website
- The Gate = Your login page
- The Key = Password
- The Guest List = Your database of users
- Remember Token = A magical badge that says “I’ve been here before!”
Let’s build this castle together! 🏗️
🔑 Chapter 1: Meet Flask-Login (Your Castle Helper)
Flask-Login is like hiring a professional gatekeeper. Instead of checking every person yourself, this helper does it for you!
What Flask-Login Does:
- ✅ Remembers who logged in
- ✅ Protects secret rooms (pages)
- ✅ Handles “remember me” magic
- ✅ Logs people out safely
Setting It Up:
# Install first: pip install flask-login
from flask import Flask
from flask_login import LoginManager
app = Flask(__name__)
app.secret_key = 'your-super-secret-key'
# Create the gatekeeper
login_manager = LoginManager()
login_manager.init_app(app)
# Where to send guests who aren't logged in
login_manager.login_view = 'login'
Think of it like: Hiring a security guard who knows all the rules!
👤 Chapter 2: The User Model (Your Guest Registry)
Every castle needs a guest book. In Flask, we create a User model to track everyone.
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer,
primary_key=True)
username = db.Column(db.String(80),
unique=True)
email = db.Column(db.String(120),
unique=True)
password_hash = db.Column(db.String(128))
Each Guest Has:
| Field | What It Means |
|---|---|
id |
Their unique guest number |
username |
Their name at the castle |
email |
How to reach them |
password_hash |
Their secret key (scrambled!) |
🎩 Chapter 3: UserMixin (Magic Powers for Your User)
UserMixin is like giving your User model superpowers! It adds four magical abilities:
from flask_login import UserMixin
class User(UserMixin, db.Model):
id = db.Column(db.Integer,
primary_key=True)
username = db.Column(db.String(80))
email = db.Column(db.String(120))
password_hash = db.Column(db.String(128))
The 4 Superpowers:
graph TD A["UserMixin Powers"] --> B["is_authenticated"] A --> C["is_active"] A --> D["is_anonymous"] A --> E["get_id"] B --> B1["&#39;Is this person<br>logged in?&#39;"] C --> C1["&#39;Is their account<br>still working?&#39;"] D --> D1["&#39;Is this a<br>mystery guest?&#39;"] E --> E1["&#39;What&#39;s their<br>guest number?&#39;"]
Simple version:
is_authenticated→ “Are you logged in?” (Yes/No)is_active→ “Is your account OK?” (Yes/No)is_anonymous→ “Are you a stranger?” (Yes/No)get_id()→ “What’s your ID number?”
🔍 Chapter 4: User Loader (Finding Guests)
When someone returns to the castle, how do we find them in our guest book? The user loader does this job!
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
How It Works:
graph TD A["Guest arrives<br>with badge #42"] --> B["User Loader"] B --> C["Search guest book<br>for #42"] C --> D{Found?} D -->|Yes| E["Welcome back,<br>Guest #42!"] D -->|No| F["Who are you?<br>Please login"]
Real-world example: It’s like a hotel checking your room key card against their system!
🔒 Chapter 5: Password Hashing (Scrambling Secrets)
NEVER store passwords as plain text! That’s like writing your diary code on a public billboard!
Instead, we hash (scramble) passwords so nobody can read them.
from werkzeug.security import (
generate_password_hash,
check_password_hash
)
class User(UserMixin, db.Model):
# ... other fields ...
def set_password(self, password):
self.password_hash = generate_password_hash(
password
)
def check_password(self, password):
return check_password_hash(
self.password_hash,
password
)
The Magic of Hashing:
| What You Type | What Gets Stored |
|---|---|
secret123 |
pbkdf2:sha256:260000$abc...xyz |
mydog |
pbkdf2:sha256:260000$def...123 |
Key point: You can turn a password INTO a hash, but you can NEVER turn a hash back into a password! It’s a one-way trip! 🚀
📝 Chapter 6: User Registration (Joining the Castle)
New guests need to sign up before they can enter!
from flask import render_template, redirect
from flask import url_for, flash, request
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form['username']
email = request.form['email']
password = request.form['password']
# Check if username exists
if User.query.filter_by(
username=username
).first():
flash('Username already taken!')
return redirect(url_for('register'))
# Create new guest
new_user = User(
username=username,
email=email
)
new_user.set_password(password)
# Add to guest book
db.session.add(new_user)
db.session.commit()
flash('Welcome to the castle!')
return redirect(url_for('login'))
return render_template('register.html')
Registration Flow:
graph TD A["New Guest Arrives"] --> B["Fill out form"] B --> C{Username taken?} C -->|Yes| D["Try different name"] D --> B C -->|No| E["Scramble password"] E --> F["Add to guest book"] F --> G["Success!<br>Now login"]
🚪 Chapter 7: User Login (Entering the Castle)
Now guests can actually enter the castle!
from flask_login import login_user
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
remember = 'remember' in request.form
# Find the guest
user = User.query.filter_by(
username=username
).first()
# Check their key
if user and user.check_password(password):
login_user(user, remember=remember)
flash('Welcome inside!')
return redirect(url_for('dashboard'))
flash('Wrong username or password!')
return render_template('login.html')
Login Flow:
graph TD A["Guest at Gate"] --> B["Show credentials"] B --> C{In guest book?} C -->|No| D["Access Denied"] C -->|Yes| E{Password correct?} E -->|No| D E -->|Yes| F["Open the gates!"] F --> G["Enter dashboard"]
🏷️ Chapter 8: Remember Me (The Magic Badge)
Sometimes guests want to stay logged in even after closing the browser. That’s what “Remember Me” does!
# In your login route:
login_user(user, remember=True)
# Configure how long to remember (optional)
app.config['REMEMBER_COOKIE_DURATION'] = timedelta(
days=7
)
How Remember Me Works:
graph TD A["Guest logs in<br>with &#39;Remember Me&#39;"] --> B["Gets special<br>cookie badge"] B --> C["Closes browser"] C --> D["Returns next day"] D --> E["Shows badge<br>to gatekeeper"] E --> F["Auto logged in!<br>No password needed"]
The cookie is like a VIP wristband at a festival. Show it, and you skip the line!
Complete Login Form:
<form method="POST">
<input type="text"
name="username"
placeholder="Username">
<input type="password"
name="password"
placeholder="Password">
<label>
<input type="checkbox"
name="remember">
Remember me
</label>
<button type="submit">Login</button>
</form>
🛡️ Protecting Castle Rooms
Once everything is set up, protect your secret rooms!
from flask_login import login_required
from flask_login import current_user
@app.route('/dashboard')
@login_required
def dashboard():
return f'Welcome, {current_user.username}!'
@app.route('/logout')
@login_required
def logout():
logout_user()
flash('Goodbye! Come back soon!')
return redirect(url_for('login'))
🎉 The Complete Picture
graph TD A["New User"] --> B["Register"] B --> C["Password Hashed"] C --> D["Saved to Database"] E["Returning User"] --> F["Login Page"] F --> G{Valid Credentials?} G -->|No| F G -->|Yes| H["login_user called"] H --> I{Remember Me?} I -->|Yes| J["Set Cookie"] I -->|No| K["Session Only"] J --> L["Access Protected Pages"] K --> L L --> M["User Loader finds user"] M --> N["current_user available"]
🌟 Quick Summary
| Concept | One-Line Explanation |
|---|---|
| Flask-Login | Your security guard helper |
| User Model | Guest book entry structure |
| UserMixin | Gives users superpowers |
| User Loader | Finds returning guests |
| Password Hashing | Scrambles passwords safely |
| Registration | Adding new guests |
| Login | Checking credentials & opening gates |
| Remember Me | VIP badge for auto-login |
🚀 You Did It!
You’ve learned how to:
- ✅ Set up Flask-Login
- ✅ Create a User model with authentication
- ✅ Use UserMixin for required methods
- ✅ Build a user loader callback
- ✅ Hash passwords safely
- ✅ Handle user registration
- ✅ Implement user login
- ✅ Add “remember me” functionality
Your castle is now secure! 🏰🔐
Next time someone tries to sneak in without a password, your gatekeeper will stop them at the door!
