在Web應用中,用戶認證是確保數據安全和個性化體驗的基礎。比如,只有登錄用戶才能訪問個人中心、提交訂單等功能。Flask-Login是一個輕量級的Flask擴展,專門用於管理用戶會話,簡化登錄、登出和權限控制的實現。本文將用最簡單的方式,帶你一步步實現基於Flask-Login的用戶登錄功能。
一、爲什麼需要Flask-Login?¶
在沒有Flask-Login時,我們需要手動處理用戶會話(比如用session存儲用戶ID)、驗證密碼、管理登錄狀態等。而Flask-Login幫我們封裝了這些邏輯,只需幾行代碼就能實現:
- 自動維護用戶會話(保存用戶ID)
- 提供@login_required裝飾器保護路由
- 處理用戶登錄、登出的核心邏輯
二、準備工作¶
首先安裝必要的庫:
pip install flask flask-login
Flask-Login的核心是LoginManager,它會管理用戶會話和登錄狀態。此外,我們需要一個“用戶模型”來存儲用戶信息(這裏用簡單的類模擬)。
三、實現步驟(附代碼)¶
1. 初始化應用和Flask-Login¶
from flask import Flask, render_template, redirect, url_for, request, flash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
# 初始化Flask應用
app = Flask(__name__)
app.secret_key = 'your-secret-key-here' # 必須設置,用於加密會話數據
# 初始化Flask-Login的LoginManager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login' # 未登錄時跳轉的路由(比如/login)
2. 創建用戶模型¶
Flask-Login要求用戶類繼承UserMixin,它會自動實現is_authenticated、is_active等屬性(無需手動寫這些方法)。我們用一個簡單的User類模擬用戶數據:
class User(UserMixin):
def __init__(self, user_id, username, password):
self.id = user_id # 用戶ID(必須)
self.username = username # 用戶名
self.password = password # 密碼(實際項目中必須加密存儲!)
# 模擬用戶數據庫(實際項目用SQLite/MySQL等)
users_db = {
1: User(id=1, username='admin', password='123456'),
2: User(id=2, username='guest', password='654321')
}
3. 實現用戶加載函數(關鍵!)¶
Flask-Login需要知道如何從會話中加載用戶。通過user_loader回調函數,根據用戶ID從數據庫中找到對應的用戶:
@login_manager.user_loader
def load_user(user_id):
"""根據用戶ID加載用戶對象"""
return users_db.get(int(user_id)) # 從模擬數據庫中查詢用戶
4. 實現登錄功能¶
創建登錄視圖函數,處理用戶輸入的用戶名和密碼,驗證成功後調用login_user(user)記錄會話:
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 獲取用戶輸入
username = request.form.get('username')
password = request.form.get('password')
# 模擬用戶驗證(實際項目需查詢數據庫+加密比對)
user = None
for u in users_db.values():
if u.username == username and u.password == password:
user = u
break
if user:
# 登錄成功:調用login_user記錄會話
login_user(user) # 會將用戶ID存入session
return redirect(url_for('home')) # 重定向到首頁
else:
flash('用戶名或密碼錯誤!') # 顯示錯誤提示
# GET請求時渲染登錄表單
return render_template('login.html')
5. 實現登出功能¶
登出時調用logout_user清除會話:
@app.route('/logout')
@login_required # 只有登錄用戶才能訪問登出路由
def logout():
logout_user() # 清除會話,用戶登出
return redirect(url_for('home')) # 重定向到首頁
6. 保護路由(驗證登錄狀態)¶
用@login_required裝飾器標記需要登錄才能訪問的路由:
@app.route('/profile')
@login_required # 未登錄用戶會被重定向到login_view
def profile():
"""個人中心:只有登錄用戶可見"""
return f"歡迎回來,{current_user.username}!"
7. 首頁和模板¶
首頁顯示歡迎信息和登錄狀態:
@app.route('/')
def home():
return render_template('home.html')
模板文件(templates/home.html):
<!DOCTYPE html>
<html>
<head>
<title>Flask-Login示例</title>
</head>
<body>
<h1>首頁</h1>
{% if current_user.is_authenticated %}
<p>當前用戶:{{ current_user.username }}</p>
<a href="{{ url_for('profile') }}">進入個人中心</a>
<br>
<a href="{{ url_for('logout') }}">登出</a>
{% else %}
<p>您尚未登錄,請<a href="{{ url_for('login') }}">登錄</a></p>
{% endif %}
</body>
</html>
登錄模板(templates/login.html):
<!DOCTYPE html>
<html>
<head>
<title>登錄</title>
</head>
<body>
<h1>登錄</h1>
{% with messages = get_flashed_messages() %}
{% if messages %}
<p style="color: red;">{{ messages[0] }}</p>
{% endif %}
{% endwith %}
<form method="POST">
<input type="text" name="username" placeholder="用戶名" required><br><br>
<input type="password" name="password" placeholder="密碼" required><br><br>
<button type="submit">登錄</button>
</form>
</body>
</html>
四、運行測試¶
- 保存上述代碼到
app.py,並在同目錄下創建templates文件夾,放入home.html和login.html。 - 運行應用:
python app.py - 訪問
http://127.0.0.1:5000,點擊“登錄”,輸入用戶名admin/guest和密碼123456/654321,即可進入個人中心。
五、注意事項¶
- 密碼安全:示例中密碼是明文存儲,實際項目必須用
bcrypt或werkzeug.security加密(例如generate_password_hash和check_password_hash)。 - 會話安全:生產環境中
app.secret_key需設置爲複雜隨機字符串,避免硬編碼。 - 擴展功能:可添加“記住我”功能(
login_user(user, remember=True))、密碼重置、權限管理等,Flask-Login支持這些高級特性。
總結¶
Flask-Login通過簡潔的API,快速實現了用戶認證的核心功能:登錄、登出、會話管理和路由保護。本文用最簡單的示例帶你入門,後續可結合數據庫和前端框架(如Bootstrap)進一步完善。
(完整代碼見上述步驟,可複製到本地運行測試)