إضافة نظام لتسجيل الدخول والخروج وحماية الموجهات الحساسة لتطبيقات Flask
تُعدّ إدارة الجلسات والتحكم في الوصول إلى الموجهات الحساسة في تطبيقات الويب من المهام الأساسية لتأمين التطبيقات وضمان استخدامها من قِبل المستخدمين المخوّلين فقط. إطار Flask الشهير لتطوير تطبيقات الويب بلغة Python يوفر مرونة كبيرة لتصميم وتنفيذ نظام تسجيل دخول وخروج كامل، إلى جانب حماية الموجهات (Routes) الحساسة التي ينبغي أن تكون مخصصة للمستخدمين المسجلين فقط.
يمثل هذا المقال دليلاً شاملاً وموسعاً حول كيفية بناء نظام متكامل لتسجيل الدخول والخروج في Flask، وحماية الموجهات الحساسة بالاعتماد على تقنيات الجلسات (Sessions)، التحقق من الهوية (Authentication)، والتحكم في الوصول (Authorization)، كما يغطي ممارسات أمان متقدمة وتفاصيل معمارية تضمن أن التطبيق يلتزم بمعايير الأمان الحديثة.
مقدمة في Flask وأنظمة المصادقة
يُعرف Flask بأنه إطار صغير (Microframework) مرن وسهل التخصيص، لا يفرض عليك بنية محددة بل يتيح للمطور بناء ما يشاء. ولكن بسبب هذا التوجه المرن، فإن معظم الأنظمة مثل تسجيل الدخول، إدارة المستخدمين، والجلسات يجب أن تُبنى يدوياً أو باستخدام إضافات مناسبة مثل Flask-Login.
يعتمد النظام الأساسي لتسجيل الدخول والخروج على النقاط التالية:
-
إنشاء نموذج تسجيل دخول.
-
التحقق من بيانات المستخدم.
-
تخزين معلومات الجلسة بعد تسجيل الدخول.
-
حماية الموجهات من الوصول غير المصرح.
-
توفير وظيفة تسجيل الخروج لمسح الجلسة.
إعداد بيئة العمل
قبل الشروع في كتابة الكود، يجب إعداد البيئة الأساسية لتطبيق Flask:
bashpython -m venv venv
source venv/bin/activate
pip install flask flask_sqlalchemy flask_login
يتم استخدام الحزم التالية:
-
Flask: إطار العمل الأساسي.
-
Flask-Login: مكتبة توفر أدوات جاهزة لإدارة الجلسات وتسجيل الدخول.
-
Flask-SQLAlchemy: لتسهيل التعامل مع قاعدة البيانات.
إعداد قاعدة البيانات ونموذج المستخدم
قاعدة البيانات ستكون جزءاً أساسياً من نظام تسجيل الدخول، ويجب أن تحتوي على جدول يمثل المستخدمين.
pythonfrom flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
db = SQLAlchemy()
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True, nullable=False)
password = db.Column(db.String(150), nullable=False)
UserMixin يوفر خصائص جاهزة للتكامل مع Flask-Login مثل is_authenticated, get_id().
إعداد التطبيق وتهيئة الإضافات
pythonfrom flask import Flask
from flask_login import LoginManager
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret-key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db.init_app(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login' # اسم المسار الذي سيتم التوجيه إليه عند محاولة دخول غير مصرح
إعداد تحميل المستخدم
python@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
هذه الدالة تقوم بتحميل المستخدم بناءً على user_id الموجود في الجلسة.
إنشاء نموذج تسجيل الدخول
نستخدم Flask وHTML لإنشاء نموذج تسجيل دخول بسيط:
pythonfrom flask import render_template, request, redirect, url_for, flash
from flask_login import login_user
from werkzeug.security import check_password_hash
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
user = User.query.filter_by(username=username).first()
if user and check_password_hash(user.password, password):
login_user(user)
return redirect(url_for('dashboard'))
else:
flash('اسم المستخدم أو كلمة المرور غير صحيحة')
return render_template('login.html')
تشفير كلمة المرور
قبل تسجيل المستخدمين الجدد، يجب تشفير كلمات المرور باستخدام مكتبة werkzeug.security:
pythonfrom werkzeug.security import generate_password_hash
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username')
password = generate_password_hash(request.form.get('password'), method='sha256')
user = User(username=username, password=password)
db.session.add(user)
db.session.commit()
return redirect(url_for('login'))
return render_template('register.html')
إنشاء وظيفة تسجيل الخروج
pythonfrom flask_login import logout_user
@app.route('/logout')
def logout():
logout_user()
return redirect(url_for('login'))
حماية الموجهات الحساسة
لمنع الوصول غير المصرح به، يتم استخدام الزخرفة @login_required من Flask-Login:
pythonfrom flask_login import login_required, current_user
@app.route('/dashboard')
@login_required
def dashboard():
return f'مرحبا، {current_user.username}'
يتم توجيه المستخدمين غير المسجلين تلقائياً إلى صفحة تسجيل الدخول المحددة في login_manager.login_view.
إدارة الجلسة وتخصيص السلوك
يمكن تخصيص مدة الجلسة وفترة التذكر (Remember Me):
python@app.route('/login', methods=['POST'])
def login():
# ...
remember = True if request.form.get('remember') else False
login_user(user, remember=remember)
# ...
يمكن أيضاً التحكم في مدة الجلسة عبر إعداد:
pythonfrom datetime import timedelta
app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=7)
طبقة حماية إضافية: حماية من CSRF
لزيادة الأمان، يجب استخدام حماية من هجمات CSRF في النماذج:
bashpip install flask-wtf
pythonfrom flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import InputRequired
class LoginForm(FlaskForm):
username = StringField('اسم المستخدم', validators=[InputRequired()])
password = PasswordField('كلمة المرور', validators=[InputRequired()])
submit = SubmitField('تسجيل الدخول')
بنية المجلدات المثالية لتطبيق Flask مع نظام تسجيل الدخول
plaintextproject/ │ ├── app/ │ ├── __init__.py │ ├── models.py │ ├── routes.py │ ├── templates/ │ │ ├── login.html │ │ ├── register.html │ │ └── dashboard.html │ └── forms.py │ ├── static/ │ ├── config.py ├── run.py
حماية متقدمة للموجهات: الأدوار والصلاحيات
في حالة التطبيقات التي تحتوي على مستخدمين بأدوار مختلفة (مثل مشرف ومستخدم عادي)، يمكن إضافة حقل “role” إلى نموذج المستخدم:
pythonclass User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
role = db.Column(db.String(50)) # مثل: admin, user
واستخدامه بهذا الشكل:
python@app.route('/admin')
@login_required
def admin_panel():
if current_user.role != 'admin':
return "غير مصرح لك بالدخول", 403
return render_template('admin.html')
جدول توضيحي للعمليات الأساسية
| الوظيفة | المسار | الحماية | وصف العملية |
|---|---|---|---|
| تسجيل الدخول | /login |
غير محمية | نموذج إدخال بيانات المستخدم والتحقق منها |
| تسجيل الخروج | /logout |
محمية | إنهاء الجلسة وإعادة التوجيه |
| لوحة التحكم | /dashboard |
محمية | عرض معلومات للمستخدم المسجل فقط |
| إدارة المشرفين | /admin |
محمية + تحقق دور | الوصول المخصص فقط للمستخدمين من نوع admin |
| تسجيل مستخدم جديد | /register |
غير محمية | إضافة مستخدم جديد مع تشفير كلمة المرور |
تدابير الأمان الموصى بها
-
استخدام HTTPS في بيئة الإنتاج.
-
استخدام كلمات مرور قوية ومشفرة.
-
حماية ضد هجمات Brute Force عبر معدلات المحاولات.
-
تسجيل محاولات الدخول وإشعارات الدخول غير المصرح.
-
استخدام مكتبة مثل
Flask-Limiterللحد من الطلبات.
دمج Flask-Login مع قواعد حماية إضافية
لزيادة الحماية، يمكن إنشاء ديكوريتر مخصص:
pythonfrom functools import wraps
from flask import abort
def admin_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.is_authenticated or current_user.role != 'admin':
abort(403)
return f(*args, **kwargs)
return decorated_function
ثم استخدامه:
python@app.route('/admin/settings')
@admin_required
def admin_settings():
return 'إعدادات المشرف'
الاستنتاج التقني
يتيح Flask وملحق Flask-Login إنشاء نظام فعال وآمن لإدارة جلسات المستخدمين وحماية الموجهات في التطبيقات، مع مرونة كبيرة تسمح بتوسيع النظام ليشمل أدوار متعددة، حماية ضد الهجمات، وتسجيل الأحداث.
استخدام مكتبات موثوقة وممارسات تطوير آمنة يعزز من ثبات وأمان التطبيق على المدى الطويل، كما يمكن دمج النظام بسهولة مع OAuth أو JWT إذا اقتضت الحاجة لذلك في بيئات أكثر تطوراً مثل التطبيقات التفاعلية أو واجهات البرمجة.

