Thứ Ba, 4 tháng 11, 2025

Bài 6: Flask + Đăng nhập / Phân quyền người dùng

🔐 BÀI 6: FLASK + ĐĂNG NHẬP & PHÂN QUYỀN NGƯỜI DÙNG

Ứng dụng Flask-Login cơ bản cho trường THPT Phan Chu Trinh


🎯 Mục tiêu bài học

  • Hiểu khái niệm xác thực (login) và phân quyền người dùng.
  • Biết cách sử dụng Flask-Login để quản lý đăng nhập.
  • Tạo tài khoản quản trị (admin) và người dùng (giáo viên).
Flask login illustration

🧩 1. Cài đặt thư viện


pip install flask flask-login

⚙️ 2. Cấu trúc dự án


flask_login/
 ├─ app.py
 ├─ users.db
 └─ templates/
      ├─ login.html
      ├─ dashboard.html
      └─ unauthorized.html

💻 3. File app.py


from flask import Flask, render_template, redirect, url_for, request
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
import sqlite3

app = Flask(__name__)
app.secret_key = 'secret123'

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

# --- Tạo DB người dùng ---
def init_db():
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        username TEXT,
        password TEXT,
        role TEXT
    )''')
    c.execute("INSERT OR IGNORE INTO users (id, username, password, role) VALUES (1,'admin','123','admin')")
    c.execute("INSERT OR IGNORE INTO users (id, username, password, role) VALUES (2,'gv1','123','teacher')")
    conn.commit()
    conn.close()

# --- Flask-Login ---
class User(UserMixin):
    def __init__(self, id, username, role):
        self.id = id
        self.username = username
        self.role = role

@login_manager.user_loader
def load_user(user_id):
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute("SELECT id, username, role FROM users WHERE id=?", (user_id,))
    data = c.fetchone()
    conn.close()
    if data:
        return User(data[0], data[1], data[2])
    return None

@app.route('/')
def home():
    return redirect('/login')

@app.route('/login', methods=['GET','POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        conn = sqlite3.connect('users.db')
        c = conn.cursor()
        c.execute("SELECT id, username, password, role FROM users WHERE username=?", (username,))
        data = c.fetchone()
        conn.close()
        if data and data[2] == password:
            user = User(data[0], data[1], data[3])
            login_user(user)
            return redirect('/dashboard')
        else:
            return "Sai tài khoản hoặc mật khẩu!"
    return render_template('login.html')

@app.route('/dashboard')
@login_required
def dashboard():
    if current_user.role == 'admin':
        message = "Bạn đang đăng nhập với quyền QUẢN TRỊ"
    else:
        message = "Bạn là GIÁO VIÊN"
    return render_template('dashboard.html', user=current_user, message=message)

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect('/login')

if __name__ == '__main__':
    init_db()
    app.run(debug=True)

📋 4. File templates/login.html


<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Đăng nhập</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light d-flex align-items-center justify-content-center vh-100">
<form method="POST" class="p-4 bg-white shadow rounded" style="width:320px;">
  <h3 class="text-center text-primary mb-3">🔐 Đăng nhập</h3>
  <input type="text" name="username" class="form-control mb-3" placeholder="Tên đăng nhập" required>
  <input type="password" name="password" class="form-control mb-3" placeholder="Mật khẩu" required>
  <button class="btn btn-primary w-100">Đăng nhập</button>
</form>
</body>
</html>

📊 5. File templates/dashboard.html


<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Trang quản lý</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container mt-5 text-center">
  <h2>Xin chào, {{ user.username }} 👋</h2>
  <p>{{ message }}</p>
  <a href="/logout" class="btn btn-danger mt-3">Đăng xuất</a>
</div>
</body>
</html>

🧠 Thử thách

  • Thêm chức năng “Đăng ký tài khoản mới”.
  • Chỉ Admin mới được xem danh sách giáo viên.
  • Giáo viên chỉ được truy cập trang riêng của mình.

© 2025 Trường THPT Phan Chu Trinh – Bài 6: Flask Login & Role System

Không có nhận xét nào:

Đăng nhận xét

Bài đăng phổ biến

💬 Bình luận

💬 Bình luận

📌 Danh sách bình luận