البرمجة

نظام تسجيل دخول وحماية Flask

إضافة نظام لتسجيل الدخول والخروج وحماية الموجهات الحساسة لتطبيقات Flask

تُعدّ إدارة الجلسات والتحكم في الوصول إلى الموجهات الحساسة في تطبيقات الويب من المهام الأساسية لتأمين التطبيقات وضمان استخدامها من قِبل المستخدمين المخوّلين فقط. إطار Flask الشهير لتطوير تطبيقات الويب بلغة Python يوفر مرونة كبيرة لتصميم وتنفيذ نظام تسجيل دخول وخروج كامل، إلى جانب حماية الموجهات (Routes) الحساسة التي ينبغي أن تكون مخصصة للمستخدمين المسجلين فقط.

يمثل هذا المقال دليلاً شاملاً وموسعاً حول كيفية بناء نظام متكامل لتسجيل الدخول والخروج في Flask، وحماية الموجهات الحساسة بالاعتماد على تقنيات الجلسات (Sessions)، التحقق من الهوية (Authentication)، والتحكم في الوصول (Authorization)، كما يغطي ممارسات أمان متقدمة وتفاصيل معمارية تضمن أن التطبيق يلتزم بمعايير الأمان الحديثة.


مقدمة في Flask وأنظمة المصادقة

يُعرف Flask بأنه إطار صغير (Microframework) مرن وسهل التخصيص، لا يفرض عليك بنية محددة بل يتيح للمطور بناء ما يشاء. ولكن بسبب هذا التوجه المرن، فإن معظم الأنظمة مثل تسجيل الدخول، إدارة المستخدمين، والجلسات يجب أن تُبنى يدوياً أو باستخدام إضافات مناسبة مثل Flask-Login.

يعتمد النظام الأساسي لتسجيل الدخول والخروج على النقاط التالية:

  • إنشاء نموذج تسجيل دخول.

  • التحقق من بيانات المستخدم.

  • تخزين معلومات الجلسة بعد تسجيل الدخول.

  • حماية الموجهات من الوصول غير المصرح.

  • توفير وظيفة تسجيل الخروج لمسح الجلسة.


إعداد بيئة العمل

قبل الشروع في كتابة الكود، يجب إعداد البيئة الأساسية لتطبيق Flask:

bash
python -m venv venv source venv/bin/activate pip install flask flask_sqlalchemy flask_login

يتم استخدام الحزم التالية:

  • Flask: إطار العمل الأساسي.

  • Flask-Login: مكتبة توفر أدوات جاهزة لإدارة الجلسات وتسجيل الدخول.

  • Flask-SQLAlchemy: لتسهيل التعامل مع قاعدة البيانات.


إعداد قاعدة البيانات ونموذج المستخدم

قاعدة البيانات ستكون جزءاً أساسياً من نظام تسجيل الدخول، ويجب أن تحتوي على جدول يمثل المستخدمين.

python
from 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().


إعداد التطبيق وتهيئة الإضافات

python
from 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 لإنشاء نموذج تسجيل دخول بسيط:

python
from 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:

python
from 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')

إنشاء وظيفة تسجيل الخروج

python
from flask_login import logout_user @app.route('/logout') def logout(): logout_user() return redirect(url_for('login'))

حماية الموجهات الحساسة

لمنع الوصول غير المصرح به، يتم استخدام الزخرفة @login_required من Flask-Login:

python
from 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) # ...

يمكن أيضاً التحكم في مدة الجلسة عبر إعداد:

python
from datetime import timedelta app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=7)

طبقة حماية إضافية: حماية من CSRF

لزيادة الأمان، يجب استخدام حماية من هجمات CSRF في النماذج:

bash
pip install flask-wtf
python
from 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 مع نظام تسجيل الدخول

plaintext
project/ │ ├── app/ │ ├── __init__.py │ ├── models.py │ ├── routes.py │ ├── templates/ │ │ ├── login.html │ │ ├── register.html │ │ └── dashboard.html │ └── forms.py │ ├── static/ │ ├── config.py ├── run.py

حماية متقدمة للموجهات: الأدوار والصلاحيات

في حالة التطبيقات التي تحتوي على مستخدمين بأدوار مختلفة (مثل مشرف ومستخدم عادي)، يمكن إضافة حقل “role” إلى نموذج المستخدم:

python
class 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 مع قواعد حماية إضافية

لزيادة الحماية، يمكن إنشاء ديكوريتر مخصص:

python
from 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 إذا اقتضت الحاجة لذلك في بيئات أكثر تطوراً مثل التطبيقات التفاعلية أو واجهات البرمجة.


المراجع