🎯 الهدف من الدرس
في الدرس السابق تعلمنا كيف نقوم بتشفير الملاحظات وفكّها عند العرض،
لكننا استخدمنا ملف مفتاح يدويًا (secret.key) بشكل بسيط.
في هذا الدرس سنتعلم الطريقة الاحترافية لتوليد المفتاح وتخزينه بشكل آمن داخل تطبيق Flask.
🧩 المفهوم الأساسي
مفتاح التشفير (Encryption Key) هو أساس الأمان.
لو تمت سرقته أو كشفه، فإن كل التشفير يصبح بلا فائدة.
لذا يجب:
- توليده مرة واحدة فقط.
- حفظه في مكان آمن لا يُرفع على GitHub أو السيرفر العام.
- تحميله من ملف بيئة (Environment Variable).
🔐 الخطوة 1: إنشاء ملف المفتاح بشكل آمن
أنشئ ملفًا باسم generate_key.py في مجلد المشروع:
from cryptography.fernet import Fernet
# توليد مفتاح جديد
key = Fernet.generate_key()
# حفظه داخل ملف نصي
with open(".flask_secret_key", "wb") as key_file:
key_file.write(key)
print("✅ تم إنشاء المفتاح وتخزينه في .flask_secret_key")
📌 عند تشغيل هذا الملف أول مرة:
python generate_key.py
سيتم إنشاء ملف جديد باسم .flask_secret_key يحتوي على المفتاح.
🔒 الخطوة 2: حماية الملف من الوصول الخارجي
في أنظمة لينكس أو macOS:
chmod 600 .flask_secret_key
وفي نظام ويندوز:
- اضغط بزر الفأرة الأيمن على الملف → خصائص (Properties)
- من الأمان (Security) → امنع الوصول عن أي مستخدمين آخرين.
⚙️ الخطوة 3: تحميل المفتاح داخل Flask بشكل آمن
في ملف app.py (أو main.py):
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from cryptography.fernet import Fernet
import os
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///notes.db'
app.secret_key = os.urandom(24) # مفتاح Flask للجلسات
# تحميل مفتاح التشفير من ملف محمي
with open(".flask_secret_key", "rb") as key_file:
key = key_file.read()
fernet = Fernet(key)
db = SQLAlchemy(app)
بهذا الشكل أصبح المفتاح لا يُكتب في الكود إطلاقًا،
بل يتم قراءته من ملف خارجي لا يُنشر أبدًا.
🧱 الخطوة 4: تخزين المفتاح في متغير بيئة (اختياري وأكثر أمانًا)
يمكنك بدلاً من حفظه في ملف، تخزينه في متغير بيئة:
📄 ملف .env
ENCRYPTION_KEY=gAAAAABnABCD1234....
📜 كود Flask
from cryptography.fernet import Fernet
import os
from dotenv import load_dotenv
load_dotenv()
key = os.getenv("ENCRYPTION_KEY").encode()
fernet = Fernet(key)
🧩 تحتاج لتثبيت مكتبة
python-dotenv:pip install python-dotenv
✅ ملخص الدرس
| الخطوة | المهمة | الهدف |
|---|---|---|
| 1 | إنشاء المفتاح بـ generate_key.py |
توليد مفتاح تشفير آمن |
| 2 | حماية الملف .flask_secret_key |
منع الوصول غير المصرح |
| 3 | تحميل المفتاح في Flask | استخدام المفتاح داخل الكود بدون كشفه |
| 4 | (اختياري) استخدام .env |
أمان إضافي ومرونة للنشر |
💪 تمرين الدرس 14:
المطلوب:
قم بتطبيق الآتي في مشروع Flask Notes App:
-
أنشئ ملف
generate_key.pyلتوليد مفتاح التشفير. - استخدم هذا المفتاح لتشفير الملاحظات كما في الدرس السابق.
- احفظ المفتاح في ملف
.flask_secret_keyأو متغير بيئة.env. - تأكد أن التطبيق يعمل بعد إعادة التشغيل، وأن الملاحظات تُفكّ بشكل صحيح.
🧠 الحل المقترح (المبسط):
# app.py
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
from cryptography.fernet import Fernet
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///notes.db'
# تحميل المفتاح من ملف خارجي
with open(".flask_secret_key", "rb") as key_file:
key = key_file.read()
fernet = Fernet(key)
db = SQLAlchemy(app)
class Note(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
note = request.form["note"]
encrypted = fernet.encrypt(note.encode()).decode()
db.session.add(Note(content=encrypted))
db.session.commit()
notes = [fernet.decrypt(n.content.encode()).decode() for n in Note.query.all()]
return render_template("index.html", notes=notes)
if __name__ == "__main__":
app.run(debug=True)

