لقد أنشأت تدفق تسجيل دخول يقوم بمصادقة تطبيق واجهة أمامية (مكتوب بـ Vue.js) لاسترجاع user_api_key الخاص بمستخدم في Discourse، متبعًا الإرشادات التي كتبها @samهنا.
تعمل المصادقة بنجاح، لكن القلق الذي لدي يتعلق بتخزين المفتاح الخاص بشكل آمن. في الوقت الحالي، يتم تخزين المفتاح الخاص محليًا في ملف .env ويُستخدم لتشفير وفك تشفير الحمولة. هل هذه طريقة آمنة لتشفير الحمولة؟ وإذا لم تكن كذلك، فما هي البدائل المتاحة لتطبيق جافا سكريبت على الواجهة الأمامية؟
كما في تطبيق Electron/Tauri؟ لا أعرف ما الذي ستختاره، أفترض أن لديهم آلية ما للتخزين الآمن، ربما إذا كنت محظوظًا يمكنك استخدام Keychain على macOS وما شابه ذلك على Windows.
إنه تطبيق ويب مُستضاف على خادم. القلق هو أنه قد يتم اعتراض الحمولة (payload) بطريقة ما إذا تم الكشف عن المفتاح الخاص. أنا على علم بأن هذا مصدر قلق عام أكثر في تشفير JavaScript، لكنني أسأل في حال وجود ممارسة أكثر أمانًا لمصادقة تطبيق ويب من Discourse.
نظام مفاتيح واجهة برمجة التطبيقات الخاصة بالمستخدمين غير مصمم لهذا السيناريو. إذا كنت ستقوم بإنشاء مفتاح خاص ثم تخزينه على الخادم نيابةً عن المستخدم، فلماذا تتعب نفسك بكل هذه الإجراءات؟ من الأفضل ببساطة توليد المفاتيح من جانب الخادم.
من الصعب جدًا عليّ تقديم أي إرشادات دون فهم المشكلة الفعلية بتفصيل أكبر. لماذا لا توفر ببساطة نقاط نهاية وسيطة (proxy endpoints) في تطبيق الويب الخاص بك وتتعامل مع جميع عمليات المصادقة داخل تطبيقك؟
بعد التحدث مع زميلي @owengot، إليك وصفًا أكثر تفصيلاً للمشكلة.
توجد تطبيق ويب مبني على Vue.js لا يحتوي على مكون خادم نشط خاص به. بل هو تطبيق ويب مستقل يستخدم واجهة برمجة تطبيقات Discourse، لذا فإن Discourse يعمل بمثابة الخادم. تشمل حالات الاستخدام استطلاعات الرأي أو النماذج المستقلة، حيث يتم نشر المحتوى في مواضيع Discourse تحت حساب المستخدم. بدا أن القدرة على إنشاء مثل هذا البرنامج دون الحاجة إلى مكونات خادم مخصصة هي بنية معمارية جيدة لهذه الاستخدامات، لذا نود في أفضل الأحوال تجنب القيام بأي شيء “من جانب الخادم”.
الآن، تعمل عملية الحصول على مفتاح مستخدم عبر واجهة برمجة التطبيقات (User-API key) كما هو متوقع، لكن اكتشف @owengot أن خطوة توليد مفتاح خاص في JavaScript تستغرق وقتًا طويلاً (تصل إلى 10 ثوانٍ، فهي غير فعالة في JavaScript…). ثم اكتشف حيلة مفادها أنه يمكن استخدام نفس المفتاح الخاص لعدة مستخدمين، لذا قام بتخزينه في ملف على المضيف الذي يستضيف التطبيق ويب، والذي يخدم أيضًا الملفات الثابتة الأخرى للتطبيق (مثل ملفات JS و CSS وما إلى ذلك). هذا يجعل العملية سريعة… لكن الآن أصبح المفتاح الخاص (1) مشتركًا و(2) مخزنًا بشكل مكشوف، مع وجود رابط يمكن الوصول إليه علنًا. يبدو ذلك، أمم، مخيفًا
لذلك قلت إنه يجب أن نسأل فريق Discourse حول الآثار الأمنية لهذه الحيلة. أرى بديلين أساسيين:
إذا كان هذا المفتاح الخاص يُستخدم “فقط” لتشفير الحمولة (payload)، فيمكننا العيش مع ذلك لأننا أيضًا نقوم بتشفير الاتصال عبر SSL/HTTPS.
لكن إذا كان معرفة هذا المفتاح الخاص يسمح بطريقة ما بحساب مفتاح مستخدم واجهة برمجة التطبيقات الناتج الذي يُستخدم لاحقًا للنشر تحت حساب شخص ما في Discourse، فسيكون هذا بالطبع يجعل هذه الحيلة غير مقبولة.