在Web應用中,用戶認證是確保系統安全的基礎。簡單來說,認證就是驗證用戶身份,權限控制則是判斷用戶是否有權訪問特定資源。本文將使用Flask框架和Session機制,從零開始實現一個簡單的用戶登錄與權限控制系統,適合初學者理解核心概念。
一、準備工作:認識Session與Flask基礎¶
在開始之前,我們先了解兩個核心概念:
- 用戶認證:通過用戶名/密碼等方式驗證用戶身份,確保只有合法用戶能訪問系統。
- Session:服務器爲每個用戶創建的臨時存儲區域,用於保存用戶狀態(如登錄狀態、用戶信息)。Flask的
session對象可直接操作Session,無需額外數據庫支持。
環境準備:
確保已安裝Flask:
pip install flask
二、創建基礎Flask應用與Session配置¶
首先,我們創建一個簡單的Flask應用,並配置Session密鑰(這是必須的,用於加密Session數據):
from flask import Flask, render_template, request, session, redirect, url_for, flash
from functools import wraps
app = Flask(__name__)
app.secret_key = 'your_secret_key_here' # 必須設置,用於加密Session(開發時可隨便寫,生產需複雜隨機字符串)
三、實現登錄功能:驗證身份與設置Session¶
登錄功能需要兩個核心部分:登錄表單和驗證邏輯。
1. 登錄表單(HTML模板)¶
創建templates/login.html文件,編寫登錄表單(支持用戶名/密碼輸入和錯誤提示):
<!DOCTYPE html>
<html>
<head>
<title>登錄</title>
</head>
<body>
<h1>用戶登錄</h1>
<!-- 顯示錯誤信息(如用戶名/密碼錯誤) -->
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<p style="color: red;">{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST">
<div>
<label>用戶名:</label>
<input type="text" name="username" required>
</div>
<div>
<label>密碼:</label>
<input type="password" name="password" required>
</div>
<button type="submit">登錄</button>
</form>
</body>
</html>
2. 處理登錄請求(驗證用戶並設置Session)¶
在app.py中添加登錄路由,處理表單提交併驗證用戶:
# 模擬用戶數據庫(實際項目中可連接MySQL/PostgreSQL等)
USER_DATABASE = {
'admin': 'admin123', # 用戶名-密碼對
'guest': 'guest456'
}
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
# 驗證用戶是否存在且密碼正確
if username in USER_DATABASE and USER_DATABASE[username] == password:
session['username'] = username # 設置Session,保存用戶身份
return redirect(url_for('dashboard')) # 登錄成功跳轉到個人中心
else:
flash('用戶名或密碼錯誤') # 錯誤提示,通過模板顯示
# GET請求直接渲染登錄頁面
return render_template('login.html')
四、權限控制:保護需要登錄的頁面¶
很多頁面(如個人中心、後臺管理)需要用戶已登錄才能訪問。我們通過@login_required裝飾器實現權限檢查:
1. 編寫登錄驗證裝飾器¶
在app.py中添加裝飾器函數,檢查Session是否存在用戶信息:
def login_required(f):
@wraps(f) # 保留原函數元信息
def decorated_function(*args, **kwargs):
if 'username' not in session: # 如果Session中沒有用戶名,說明未登錄
flash('請先登錄')
return redirect(url_for('login')) # 重定向到登錄頁
return f(*args, **kwargs) # 已登錄,繼續執行目標函數
return decorated_function
2. 保護個人中心頁面¶
創建需要登錄的個人中心頁面,使用裝飾器保護:
@app.route('/dashboard')
@login_required # 必須登錄才能訪問
def dashboard():
return render_template('dashboard.html', username=session['username']) # 傳遞用戶名到模板
五、實現登出功能¶
登出需要清除Session中的用戶信息,讓用戶狀態失效:
@app.route('/logout')
def logout():
session.pop('username', None) # 從Session中刪除用戶名
flash('已成功登出')
return redirect(url_for('index')) # 登出後跳回首頁
六、完善頁面與測試¶
爲了讓用戶體驗更完整,我們補充首頁和登出後的頁面:
1. 首頁模板(templates/index.html)¶
允許未登錄用戶訪問,顯示登錄入口:
<!DOCTYPE html>
<html>
<head>
<title>首頁</title>
</head>
<body>
<h1>歡迎來到系統</h1>
<a href="{{ url_for('login') }}">登錄</a> | <a href="{{ url_for('dashboard') }}">個人中心</a>
</body>
</html>
2. 個人中心模板(templates/dashboard.html)¶
僅登錄用戶可見,顯示用戶名和登出入口:
<!DOCTYPE html>
<html>
<head>
<title>個人中心</title>
</head>
<body>
<h1>歡迎,{{ username }}!</h1>
<a href="{{ url_for('logout') }}">登出</a>
</body>
</html>
3. 啓動應用並測試¶
運行app.py:
if __name__ == '__main__':
app.run(debug=True)
測試流程:
1. 訪問 http://127.0.0.1:5000,首頁顯示正常,點擊“個人中心”會被重定向到登錄頁。
2. 輸入測試賬號(如admin/admin123或guest/guest456),登錄成功後進入個人中心。
3. 點擊“登出”,Session被清除,再次訪問個人中心會重定向到登錄頁。
七、總結¶
通過本文,我們學習了:
1. Session基礎:使用Flask的session對象存儲用戶狀態,通過secret_key加密數據。
2. 用戶認證:通過表單提交和硬編碼數據庫實現簡單登錄驗證。
3. 權限控制:使用裝飾器檢查Session是否存在,保護需要登錄的頁面。
4. 用戶登出:通過session.pop()清除用戶狀態。
擴展方向:
- 連接數據庫驗證用戶(如使用SQLAlchemy)。
- 實現多角色權限(如普通用戶/管理員)。
- 添加密碼加密(避免明文存儲,使用bcrypt等庫)。
Flask Session爲初學者提供了簡單易用的身份驗證方案,掌握這些基礎後,可逐步構建更復雜的Web應用。