在Web應用中,用戶認證是確保系統安全的基礎。簡單來說,認證就是驗證用戶身份,權限控制則是判斷用戶是否有權訪問特定資源。本文將使用Flask框架和Session機制,從零開始實現一個簡單的用戶登錄與權限控制系統,適合初學者理解核心概念。

一、準備工作:認識Session與Flask基礎

在開始之前,我們先了解兩個核心概念:

  1. 用戶認證:通過用戶名/密碼等方式驗證用戶身份,確保只有合法用戶能訪問系統。
  2. 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/admin123guest/guest456),登錄成功後進入個人中心。
3. 點擊“登出”,Session被清除,再次訪問個人中心會重定向到登錄頁。

七、總結

通過本文,我們學習了:
1. Session基礎:使用Flask的session對象存儲用戶狀態,通過secret_key加密數據。
2. 用戶認證:通過表單提交和硬編碼數據庫實現簡單登錄驗證。
3. 權限控制:使用裝飾器檢查Session是否存在,保護需要登錄的頁面。
4. 用戶登出:通過session.pop()清除用戶狀態。

擴展方向
- 連接數據庫驗證用戶(如使用SQLAlchemy)。
- 實現多角色權限(如普通用戶/管理員)。
- 添加密碼加密(避免明文存儲,使用bcrypt等庫)。

Flask Session爲初學者提供了簡單易用的身份驗證方案,掌握這些基礎後,可逐步構建更復雜的Web應用。

小夜