المصادقة الثنائية (2FA) ونظام التفعيل الفوري للإضافة بضغطة زر (Token SSO)
مع التوسع الكبير في أعمال صناع المحتوى والناشرين ومصممي المنتجات الرقمية على منصة صانع المنتجات الرقمية (Digital Products Maker)، أصبحت حماية الحسابات وسلاسة إعداد أدوات العمل ضرورة قصوى. فتعرض أي حساب للاختراق قد يؤدي إلى فقدان التراخيص التجارية أو تسريب الأصول الرقمية. وفي الوقت نفسه، يُعتبر نقل مفاتيح التراخيص المعقدة يدوياً ونسخها ولصقها داخل إضافة المتصفح عبئاً يؤدي إلى أخطاء الإدخال وتعطيل سير العمل.
لحل هاتين العقبتين بأعلى المعايير الهندسية، تم تزويد المنصة بنظام المصادقة الثنائية (2FA) المعتمد على خوارزمية TOTP (RFC 6238)، بالتكامل مع بروتوكول التفعيل الفوري للإضافة بضغطة زر (Single Sign-On) عبر رموز مؤقتة، و نظام بث التحديثات البرمجية المحمية.
1. المخطط المعماري وأنظمة الأمان الفرعية
تتكامل منظومة الأمان والمصادقة عبر ثلاثة محاور رئيسية:
- محرك المصادقة الثنائية (RFC 6238 TOTP Engine): توليد مفاتيح Base32 مشفرة بطول 160 بت، وإنشاء رموز الاستجابة السريعة (
QR Code) المعتمدة، والتحقق من الرموز المتحركة كل 30 ثانية. - جسر التفعيل الفوري بضغطة زر (SSO Token Bridge): إصدار رموز UUID مشفرة صالحة لمدة 60 ثانية (
extension_auth_tokens) يتم تبادلها عبر رسائل المتصفح الآمنة لربط الإضافة دون كشف مفتاح الترخيص الخام. - منظومة بث التحديثات البرمجية المحمية: تخزين حزم التحديثات البرمجية في مسار خاص خارج مسار الويب العام (
protected_uploads) وبثها حصرياً بعد التحقق التزامني من صلاحية الترخيص.
+---------------------------------------------------------------------------------------------------+
| لوحة تحكم بوابة العملاء (/portal) |
+--------------------------------+----------------------------------+-------------------------------+
| |
[1. إعداد 2FA] | [2. تفعيل الإضافة بضغطة] |
v v
+--------------------------------+------+ +-------------------+-------------------------------+
| محرك المصادقة الثنائية TOTP | | متحكم توليد رموز SSO المؤقتة |
| - توليد المفتاح speakeasy | | - إنشاء معرف فريد crypto.randomUUID() |
| - تخزين المفتاح في customer_totp... | | - صلاحية 60 ثانية في extension_auth_tokens |
| - رسم صورة QR عبر qrcode.toDataURL() | | - التمرير للإضافة عبر window.postMessage |
+--------------------------------+------+ +-------------------+-------------------------------+
| |
[رمز 6 أرقام] | | [الرمز المؤقت + معرف الجهاز]
v v
+--------------------------------+------+ +-------------------+-------------------------------+
| اعتراض تحدي تسجيل الدخول | | متحكم تفعيل الترخيص المشفر بالرمز |
| - إيقاف الدخول غير الموثق بـ 2FA | | - POST /api/license/activate-by-token |
| - التحقق من الرمز المتحرك الحالي | | - مطابقة ترخيص العميل وحدود الأجهزة المسموحة |
| - إصدار رمز JWT صالح لـ 7 أيام | | - إصدار المفتاح السري للجهاز device_secret |
+---------------------------------------+ +---------------------------------------------------+
2. دورة حياة المصادقة الثنائية (RFC 6238 TOTP)
يتوافق نظام المصادقة الثنائية في المنصة توافقاً كاملاً مع معيار RFC 6238 (Time-Based One-Time Password)، مما يجعله متوافقاً مع كافة تطبيقات المصادقة الشهيرة مثل Google Authenticator و Microsoft Authenticator و Apple Passwords و Authy و 1Password.
2.1 هيكل جدول قاعدة البيانات (customer_totp_secrets)
تُخزن المفاتيح السرية في جدول مخصص يرتبط بحساب العميل بعلاقة فريدة:
CREATE TABLE customer_totp_secrets (
id INT AUTO_INCREMENT PRIMARY KEY,
customer_account_id INT NOT NULL UNIQUE,
secret VARCHAR(255) NOT NULL,
is_enabled BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (customer_account_id) REFERENCES customer_accounts(id) ON DELETE CASCADE
);
2.2 توليد المفتاح السري ورمز الاستجابة السريعة (POST /api/portal/2fa/generate)
عند بدء إعداد المصادقة الثنائية، يقوم الخادم بإنشاء مفتاح Base32 مشفر ورسم صورة QR برمجياً لإتاحة مسحها بكاميرا الهاتف:
// server/src/features/customer-portal/controller.ts
import speakeasy from "speakeasy";
import qrcode from "qrcode";
export async function generate2FA(req: PortalRequest, res: Response) {
try {
const customerId = req.customer?.id;
if (!customerId) return res.status(401).json({ error: "غير مصرح" });
// جلب بريد العميل لإضافته كتسمية داخل تطبيق المصادقة
const [custRows]: any = await pool.query(
"SELECT email FROM customer_accounts WHERE id = ?",
[customerId]
);
if (custRows.length === 0) return res.status(404).json({ error: "الحساب غير موجود" });
const email = custRows[0].email;
// توليد مفتاح سري بنظام Base32
const secret = speakeasy.generateSecret({
name: `AI Digital Products (${email})`
});
// حفظ المفتاح في حالة غير مفعلة مؤقتاً (is_enabled = 0)
const [existingRows]: any = await pool.query(
"SELECT id FROM customer_totp_secrets WHERE customer_account_id = ?",
[customerId]
);
if (existingRows.length > 0) {
await pool.query(
"UPDATE customer_totp_secrets SET secret = ?, is_enabled = 0 WHERE customer_account_id = ?",
[secret.base32, customerId]
);
} else {
await pool.query(
"INSERT INTO customer_totp_secrets (customer_account_id, secret, is_enabled) VALUES (?, ?, 0)",
[customerId, secret.base32]
);
}
// توليد صورة QR على هيئة Data URL لعرضها فورياً
const qrDataURL = await qrcode.toDataURL(secret.otpauth_url || "");
res.json({ secret: secret.base32, qrCode: qrDataURL });
} catch (err: any) {
res.status(500).json({ error: "فشل توليد مفتاح المصادقة الثنائية." });
}
}
2.3 التحقق والتفعيل النهائي (POST /api/portal/2fa/verify)
لتجنب إغلاق الحساب في حال عدم مسح الرمز بشكل صحيح، لا يتم تفعيل المصادقة الثنائية تلقائياً إلا بعد أن يُدخل المستخدم أول رمز مكون من 6 أرقام يثبت ربطه للتطبيق بنجاح:
export async function verify2FA(req: PortalRequest, res: Response) {
try {
const customerId = req.customer?.id;
if (!customerId) return res.status(401).json({ error: "غير مصرح" });
const { token } = req.body;
if (!token) return res.status(400).json({ error: "الرمز مطلوب" });
const [rows]: any = await pool.query(
"SELECT secret FROM customer_totp_secrets WHERE customer_account_id = ?",
[customerId]
);
if (rows.length === 0) return res.status(400).json({ error: "لم يتم بدء إعداد المصادقة الثنائية" });
// التحقق من الرمز المكون من 6 أرقام ضمن نافذة التوقيت الحالية
const verified = speakeasy.totp.verify({
secret: rows[0].secret,
encoding: "base32",
token
});
if (verified) {
// تفعيل المصادقة الثنائية رسمياً للحساب
await pool.query(
"UPDATE customer_totp_secrets SET is_enabled = 1 WHERE customer_account_id = ?",
[customerId]
);
res.json({ message: "تم تفعيل المصادقة الثنائية بنجاح" });
} else {
res.status(400).json({ error: "رمز المصادقة غير صالح" });
}
} catch (err: any) {
res.status(500).json({ error: "فشل التحقق من رمز المصادقة." });
}
}
2.4 تحدي تسجيل الدخول المحمي بـ 2FA
عند تسجيل الدخول في البوابة (POST /api/portal/login) لحساب مفعل عليه 2FA، يوقف الخادم عملية إصدار جلسة الدخول ويعيد:
{
"requires2FA": true,
"message": "يرجى إدخال رمز المصادقة الثنائية المكون من 6 أرقام."
}
تتحول الواجهة تلقائياً لطلب رمز المصادقة المتحرك قبل تسليم رمز JWT المعتمد.
3. التفعيل الفوري للإضافة بضغطة زر (One-Click SSO Activation)
يحل هذا الابتكار مشكلة كتابة أو نسخ مفتاح الترخيص الطويل في إضافة كروم. بضغطة زر واحدة من لوحة تحكم بوابة العملاء، يتم تفعيل الإضافة على الجهاز الجديد فورياً.
+------------------+ +--------------------+ +-------------------+
| إضافة متصفح كروم | | بوابة العملاء | | الخادم |
+--------+---------+ +---------+----------+ +---------+---------+
| | |
| 1. فتح البوابة مع ?auth=1 | |
|---------------------------->| |
| | 2. طلب رمز POST /token |
| |----------------------------->|
| | | 3. توليد UUID
| | | (صلاحية 60 ثانية)
| | 4. إعادة { token: UUID } |
| |<-----------------------------|
| 5. تمرير الرمز للمتصفح | |
|<----------------------------| |
| |
| 6. تفعيل الإضافة بالرمز POST /api/license/activate-by-token|
|----------------------------------------------------------->|
| | 7. التحقق من صلاحية الرمز
| | 8. ربط بصمة الجهاز
| | 9. إصدار المفتاح السري
| 10. الرد بنجاح التفعيل وإرجاع مفتاح التشفير للجهاز |
|<-----------------------------------------------------------|
3.1 إصدار الرمز المؤقت (POST /api/portal/extension-token)
يقوم الخادم بتوليد معرف عشوائي مشفر UUID بصلاحية محددة بـ 60 ثانية فقط:
export async function generateExtensionToken(req: PortalRequest, res: Response) {
try {
const token = crypto.randomUUID();
const customerId = req.customer!.id;
const expiresAt = new Date(Date.now() + 60000); // 60 ثانية فقط
await pool.query(
"INSERT INTO extension_auth_tokens (token, customer_id, expires_at) VALUES (?, ?, ?)",
[token, customerId, expiresAt]
);
res.json({ token });
} catch (error) {
res.status(500).json({ error: 'حدث خطأ في توليد رمز التفعيل' });
}
}
3.2 التفعيل الفردي وربط بصمة الجهاز (POST /api/license/activate-by-token)
تلتقط الإضافة الرمز وترسله إلى الخادم مع البصمة التعريفية للحاسوب (device_uuid):
- يتأكد الخادم من أن الرمز لم يُستخدم مسبقاً (
used = 0) ولم تنتهِ مهلة الـ 60 ثانية. - يجلب الترخيص النشط المرتبط بالعميل ويتأكد من توفر منافذ أجهزة شاغرة.
- يصدر مفتاح تشفير عشوائي للجهاز (
device_secret) ويسجل الجهاز فيlicense_devices. - يقوم الخادم بتعطيل الرمز فوراً (
UPDATE extension_auth_tokens SET used = 1) لمنع استخدامه مرة أخرى.
4. البث الآمن لحزم التحديثات البرمجية المحمية
لحماية الكود المصدري لإضافة المتصفح ومنع تداول النسخ المقرصنة، تُخزن حزم التحديثات في مجلد خاص (protected_uploads) غير متاح للتصفح المباشر.
4.1 التحقق التزامني من صلاحية التراخيص (GET /api/portal/downloads/:id/file)
قبل بدء بث ملف التحديث (ZIP)، يفحص الخادم قاعدة البيانات للتأكد من امتلاك العميل ترخيصاً نشطاً وغير منتهٍ:
SELECT l.license_key
FROM licenses l
LEFT JOIN plans p ON l.plan_id = p.id
WHERE l.customer_account_id = ?
AND l.is_active = TRUE AND l.is_banned = FALSE
AND (p.is_lifetime = 1 OR l.expires_at IS NULL OR l.expires_at >= NOW());
- في حال انتهاء الاشتراك، يرفض الخادم التحميل برمز HTTP 403 Forbidden:
"انتهت صلاحية ترخيصك أو أنه غير نشط. يرجى تجديد خطتك لتنزيل ملفات الإضافة." - في حال كان الترخيص نشطاً، يتم بث الملف بنظام التدفق (
Stream)، وتسجيل العملية في جدولupdate_download_logsمع زيادة عداد التحميلات.
5. دليل استكشاف الأخطاء ومعالجة استثناءات الأمان
| حالة الخطأ | سبب الحدوث والشرط البرمجي | رمز الاستجابة | الحل والإجراء الموصى به |
|---|---|---|---|
| فشل التحقق من رمز 2FA | إدخال رمز خاطئ أو انتهاء صلاحية الـ 30 ثانية للرمز الحالي. | 400 Bad Request{"error": "Invalid 2FA token"} |
التأكد من ضبط توقيت الهاتف وإدخال الرمز الجديد الظاهر في التطبيق. |
| انتهاء مهلة رمز SSO | تأخر الإضافة في إرسال الرمز وتجاوز مهلة الـ 60 ثانية. | 403 Forbidden{"error": "Invalid or expired activation token"} |
النقر مرة أخرى على "تفعيل الإضافة" في بوابة العملاء لتوليد رمز فوري جديد. |
| إعادة استخدام رمز SSO | محاولة استخدام رمز تم استخدامه وتفعيله مسبقاً. | 403 Forbidden{"error": "Activation token already used"} |
الرموز تعمل لمرة واحدة فقط؛ يلزم توليد رمز جديد من البوابة. |
| رفض تحميل التحديثات | محاولة تنزيل تحديث لحساب لا يملك ترخيصاً نشطاً. | 403 Forbidden{"error": "Your license has expired or is inactive..."} |
تجديد الاشتراك أو الترقية من تبويب الفوترة في بوابة العملاء. |
| امتلاء منافذ الأجهزة | محاولة تفعيل الإضافة وجدول الأجهزة قد وصل للحد الأقصى. | 403 Forbidden{"error": "Maximum device limit reached..."} |
التوجه إلى "تراخيصي" وإلغاء ربط الأجهزة القديمة غير المستخدمة. |
6. جدول المصطلحات التقنية المعتمدة (عربي - إنجليزي)
| المصطلح المعتمد باللغة العربية | English Term | سياق الاستخدام والتنفيذ البرمجي |
|---|---|---|
| المصادقة الثنائية (2FA) | Two-Factor Authentication | طبقة الأمان الإضافية المعتمدة على معيار TOTP RFC 6238. |
| رمز تطبيق المصادقة (TOTP) | Authenticator Code | الرمز الرقمي الديناميكي المكون من 6 أرقام والمتجدد كل 30 ثانية. |
| التفعيل الفوري للإضافة بضغطة زر | One-Click Extension Activation | بروتوكول تفعيل الإضافة الذاتي عبر رموز UUID المؤقتة. |
| رمز المصادقة الموحدة المؤقت | Single Sign-On (SSO) Token | رمز أحادي الاستخدام محفوظ في جدول extension_auth_tokens بمهلة 60 ثانية. |
| البث الآمن للملفات المحمية | Protected Uploads Stream | إرسال حزم التحديثات مباشرة من المسار المشفر بعد فحص التراخيص. |
| ربط البصمة التعريفية للجهاز | Hardware Fingerprint Binding | إقران معرّف الجهاز (device_uuid) بالمفتاح السري في قاعدة البيانات. |
| التحقق من أهلية وصلاحية الترخيص | License Entitlement Verification | الفحص اللحظي لصلاحية الترخيص وعدم حظره أو انتهاء مدته. |
الخلاصة والتوصيات الهندسية
تُجسد منظومة المصادقة الثنائية (2FA) و التفعيل الفوري للإضافة بضغطة زر (Token SSO) و بث التحديثات المحمية قمة التوازن بين الأمان التشفيري الصارم و تجربة الاستخدام الفائقة السلاسة. وبفضل هذا التكامل، يتمتع مستخدمو صانع المنتجات الرقمية بحماية مطلقة لحساباتهم وأصولهم مع سهولة تامة في إعداد ومزامنة أجهزتهم للبدء في الإنتاج والربح على الفور.



