في بعض الأحيان يصبح من الضروري نقل البيانات بين تطبيق يعمل في متصفح وبرنامج يعمل على نفس النظام الذي يعمل عليه المتصفح. قد يكون هذا ضروريًا ، على سبيل المثال ، إذا احتجنا إلى العمل مع جهاز متصل محليًا. قارئ البطاقة الذكية ، مفتاح تشفير الأجهزة وهلم جرا.

صورة من هنا
أول من يتبادر إلى الذهن هي ثلاث طرق لحل هذه المشكلة:
- القيام بأدوات المتصفح ، أو كتابة المكونات الإضافية لهم
- تنظيم تبادل البيانات من خلال الخلفية ، بمثابة وسيط
- أضف خدمة HTTP إلى البرنامج ، وقم بالوصول إليها مباشرة من المتصفح
يبدو العنصر الثالث جيدًا ، ويسمح لك بإزالة التفويض في البرنامج ، ولا يتطلب أي واجهة مستخدم على الإطلاق. دعونا نحاول تنفيذه عن طريق كتابة برنامج في C # ضمن .NET Framework 4. نظرًا لأننا نتحدث عن .NET ، فإن الحل سيكون فقط لنظام Windows (XP وأحدث). سنجعل تطبيق الويب على الزاوي.
لماذا لا 1 و 2؟
العنصر الأول سيؤدي بالتأكيد إلى الكثير من الألم ، يجب عليك دعم المتصفحات بشكل منفصل ، يمكنك أن تفعل الكثير من كل شيء في المكونات الإضافية للمتصفح. ومع ذلك ، من الناحية النظرية ، من الممكن العمل مع البطاقات الذكية من خلال المكونات الإضافية. لكنك تحتاج إلى طريقة أكثر بساطة.
النقطة الثانية سهلة التنفيذ ، ولكن بالنسبة لهذا المخطط ، سيتعين عليك الحصول على إذن ، ليس فقط على الموقع ، ولكن أيضًا في التطبيق المحلي. هذا يعني أن هناك حاجة إلى نوع من الواجهة ، ولكن عند تغيير كلمة المرور ، ستكون هناك حاجة أيضًا إلى إعادة التفويض في البرنامج. بالإضافة إلى ذلك ، في شبكات الشركات ستكون هناك مشاكل إضافية مع الشبكة ، وغالبًا ما يكون لديهم إمكانية الوصول إلى الإنترنت من خلال الوكلاء ذوي التصفية القوية والترخيص ، كما يجب عليك إنشاء واجهة لتكوين الوكلاء ، ولا يمكنك دائمًا التخلص من الإعدادات التلقائية. سيكون من الأصعب على مستخدم بعيد عن تكنولوجيا المعلومات التعامل مع هذا ؛ سننشئ المزيد من أعمال الدعم الفني. بالطبع ، يمكنك إنشاء حزمة تثبيت بشكل فردي لكل مستخدم لإزالة الحاجة إلى إذن أساسي ، ولكن هذا سيضيف فقط إلى المشاكل.
ما علاقة HTTPS به؟
عندما يتم تشغيل أحد المواقع عبر HTTPS ، تمنع المتصفحات تنزيل المحتوى النشط باستخدام HTTP. ومع ذلك ، وفقًا لمنطق الأشياء ، يجب أن تعتبر المتصفحات أن الطلب إلى الجهاز المحلي عبر HTTP آمن ، ولا يجب حظره. اتضح أن هذا ليس كذلك.
يوضح الجدول نتائج دراسة صغيرة لسلوك المتصفحات على نظام Windows:
يعرض الجدول سلوك المستعرضات عند محاولة تقديم طلب على العنوان المناسب. تتصرف المتصفحات على محرك Chromium بشكل مشابه لمتصفح Chrome ، ويشبه سلوك Edge 44 سلوك IE 11. يتم إصدار شهادة صالحة لـ HTTPS ، موقعة بشهادة الجذر موقعة ذاتيًا. سلوك https://127.0.0.1 و https: // localhost هو نفسه ، فقط مقابل 127.0.0.1 ، ثم تحتاج إلى إصدار شهادة أيضًا ، ونادراً ما يتم العثور على شهادات لعناوين IP ، ولذا فإننا نحذف هذه النقطة.
كل شيء يعمل في كروم. يستخدم Chrome و IE مخزن شهادات النظام ، لذلك يعمل HTTPS أيضًا فيهما. يستخدم Firefox متجر الشهادات الخاص به ، لذلك لا يثق في شهادة موقعة ذاتيا. لا يثق Firefox و IE في اسم المضيف المحلي ، وهذا صحيح ، لأنه لا يوجد أحد يضمن أنه يحل إلى 127.0.0.1 (على الرغم من أنه يمكنهم التحقق من ذلك تمامًا كما يفعل Chrome).
المشكلة الرئيسية: لا يسمح IE بالوصول إلى البرنامج عبر HTTP. لذلك ضجة مع شهادات لا يمكننا تجنبها.
للعمل مع المتصفحات ، ستحتاج أيضًا إلى تحديد الرؤوس الصحيحة للوصول إلى التحكم في الوصول والوصول إلى التحكم في السماح ورؤوس الوصول إلى التحكم في الرؤوس ( CORS ) في البرنامج.
شهادة SSL
يمكنك إنشاء سجل DNS للمجال الخاص بك ، على سبيل المثال local.example.com ، والذي سيتم حله على 127.0.0.1. إصدار شهادة طبقة المقابس الآمنة لهذا المجال ، وتوزيعها مع البرنامج. يجب عليك توزيع المفتاح الخاص لهذه الشهادة مع البرنامج. هذا غير مناسب تماما. وستحتاج الشهادة في البرنامج أيضًا إلى التحديث.
لن تثق IE بشهادة SSL موقعة ذاتياً ، يجب أن تكون موقعة بشهادة الجذر الموثوق بها (ويمكن أن تكون موقعة ذاتياً).
يمكنك إنشاء شهادة الجذر وشهادة SSL وتوزيعها مع البرنامج ، إضافة إلى متجر الشهادات المحلي. يبدو غير آمن. وقد يكون من الضروري أيضًا إلغاء أو تجديد الشهادة. لذلك ، سنقوم بإنشاء شهادات مع مفاتيح مباشرة على جهاز الكمبيوتر الخاص بالمستخدم في البداية الأولى للبرنامج.
إنشاء شهادات في C #
بالنسبة إلى .NET ، هناك مكتبة BouncyCastle يمكنها القيام بكل ما نحتاج إليه. المشكلة الوحيدة هي أنه من أجل إضافة شهادة إلى المتجر ، سوف تضطر إلى طلب زيادة في الامتيازات. ستحتاج أيضًا إلى حقوق مرتفعة لاستخدام netsh لتأمين الشهادة إلى منفذ معين في النظام.
netsh http add sslcert ipport=0.0.0.0:{PORT} certhash={certThumbprint}
في المثال ، يقوم أسلوب RegisterSslOnPort في فئة SslHelper بهذه المهمة.
خدمة HTTP في برنامج C #
لإنشاء خادم HTTP (S) خفيف الوزن ، نستخدم مكتبة Nancy . Nancy عبارة عن إطار ويب خفيف الوزن لـ .NET ، بسيط وسهل الاستخدام. لقد كتب الكثير عنه ، بما في ذلك على حبري . بفضل وحدة Nancy.SelfHosting ، يمكننا استضافة تطبيقنا دون استخدام IIS.
على سبيل المثال ، لنقم بإنشاء نقطة نهاية تتعامل مع إضافة رقمين. من المهم هنا تعيين رؤوس CORS الصحيحة ، وإلا فلن يقوم المتصفح بتنفيذ طلب إلى API الخاصة بنا.
نانسيمودول public class CalcNancyModule : NancyModule { public CalcNancyModule() {
أضف تهيئة نانسي إلى طلبنا ، ونحن على استعداد للمعركة.
نانسي التهيئة var hostConfigs = new HostConfiguration(); hostConfigs.UrlReservations.CreateAutomatically = true; hostConfigs.RewriteLocalhost = false; var uris = new Uri[] { new Uri($"http://localhost:{HTTPPORT}"), new Uri($"http://127.0.0.1:{HTTPPORT}"), new Uri($"https://localhost:{HTTPSPORT}") }; using (var host = new NancyHost(hostConfigs, uris)) { host.Start(); }
في البداية ، تحتاج إلى إنشاء شهادات ووضعها في المتجر ، وطلب الحقوق المناسبة. يتم استخدام فئة SslHelper لهذه التلاعب ، حيث تقوم CheckOrCreateCertificates العامة الوحيدة بهذه المهمة. كمعلمات ، يتم تمرير شهادات SubjectName إليها. تتحقق الطريقة مما إذا كانت الشهادات اللازمة متوفرة ويقوم النظام ، إن لم يكن ، بإنشاءها.
لمحاكاة العمل الجاد والتأخير الطويل في المثال ، أضف Thread.Sleep (1000) إلى مكالمات API الخاصة بنا.
على هذا التطبيق جاهز للتشغيل ، انتقل إلى الويب.
تطبيق الويب
كما ترون من جدول سلوك المتصفح ، لا يمكن الاستغناء عن نقطة نهاية واحدة ؛ يجب استخدام نقطتين على الأقل:
في تطبيق الويب ، نحتاج إلى تحديد ما إذا كنا في IE (أو Edge) - استخدم HTTPS ، إن لم يكن - HTTP. يمكنك جعله أكثر موثوقية ولا يمكنك معرفة أي متصفح نتواجد فيه ، ولكن حاول فقط تنفيذ طلب على طريقة GET / Calc بواجهة برمجة التطبيقات الخاصة بنا ، إذا نجح الطلب ، فنحن نعمل ، إن لم يكن ، نحاول بروتوكول آخر.
كل هذا ضروري فقط إذا كان تطبيق الويب نفسه يستخدم HTTPS ، لأنه عند استخدام بروتوكول HTTP ، لا تفرض المتصفحات قيودًا على الطلبات ، ولكن هناك حاجة إلى رؤوس CORS الصحيحة فقط.
في التطبيق الزاوي ، قم بإنشاء خدمة InteractionService التي ستتحقق من توفر نقطة النهاية المحلية أولاً عبر HTTP ، ثم بواسطة HTTPS. يتم إجراء التحقق من خلال طريقة checkAvailable ، وتكون نتيجة الفحص متاحة عند الاشتراك في المتغير المتوفر من النوع BehaviorSubject بالقيمة الأولية false.
نضيف عمل إضافة أرقام إلى مكون AppComponent. عند النقر فوق الزر "حساب" ، يقدم تطبيق الويب طلبًا للحصول على / حساب / إضافة؟ Num1 = {num1} & num2 = {num2}. يتم عرض الإجابة أو الخطأ في حقل النتيجة.
عند تصحيح الأخطاء ، حتى عبر HTTPS ، قد لا تلاحظ مشاكل ، لأن المجال الخاص بالطلبات سيكون هو نفسه - المضيف المحلي. لذلك ، تحتاج إلى اختبار التطبيق باسم مجال مختلف.
لتبسيط عمل نشر تطبيق ويب قدر الإمكان ، نستخدم الخدمة https://stackblitz.com ، وهذا هو IDE على شبكة الإنترنت للزاوي وليس فقط مع ذوق VSCode. التطبيق النهائي متاح على الرابط .
ويمكنك حفر الكود هنا .
لن يعمل التطبيق بشكل تفاعلي على stackblitz ، تحتاج إلى فتحه في علامة تبويب خاصة منفصلة ، أو في متصفح آخر على https://angular-pfwfrm.stackblitz.io .
كيف تجرب؟
يتم تشغيل تطبيق الويب بسهولة باستخدام stackblitz ، ببساطة عن طريق النقر على الرابط https://angular-pfwfrm.stackblitz.io .
يمكنك تشغيل تطبيق الويب محليًا.
لهذا تحتاجللقيام بذلك ، تحتاج إلى استنساخ المستودع:
git clone https://github.com/jdtcn/InteractionExample.git cd InteractionExample
في المجلد AngularWebApp ، تحتاج إلى تشغيل الأوامر:
npm install ng serve --ssl true
سيكون تطبيق الويب متاحًا على https: // localhost: 4200 /
يمكن ترجمة التطبيق المحلي من المثال (افتح CsClientApp.sln من مجلد CsClientApp) باستخدام Visual Studio وتشغيله ، أو استخدام البرنامج النصي لبرنامج LINQPad .
إذا كنت من مطوري .NET ولا تستخدم LINQPad ، فتأكد من قراءته ، وهو أمر لا غنى عنه في التطوير. لتشغيل المثال ، تحتاج إلى فتح البرنامج النصي في LINQPad'e (أول مرة تحتاج فيها إلى تشغيل LINQPad مع حقوق المسؤول من أجل تثبيت الشهادات) ، وتثبيت حزم nouget BouncyCastle ، Nancy ، Nancy.Hosting.Self ، ثم قم بتشغيل البرنامج النصي. بعد ذلك ، يمكنك النقر فوق الزر "حساب" في تطبيق الويب ، والحصول على نتيجة العملية.
السلامة
من المهم تكوين رؤوس CORS بشكل صحيح في تطبيق حقيقي حتى لا يتمكن الأشرار من المواقع الأخرى من الوصول إلى برنامجنا. إذا كانت لدى الشرير الفرصة للعمل بامتيازات المستخدم على جهاز الكمبيوتر الخاص به وتجاوز اختبار CORS ، فسيكون قادرًا على القيام بكل ما يمكن لبرنامجنا القيام به.
في أي حال ، يجب أن يعمل البرنامج مع الحد الأدنى من الحقوق ، وإذا كان يفعل شيء حساس مع الوثائق ، تحتاج إلى إضافة طلبات لتأكيد العمليات إليها.
الخاتمة
اتضح أن المهمة البسيطة على ما يبدو ضخمة ، بل تتطلب عكازات إضافية للعمل مع الشهادات.
أداء هذا النهج بشكل جيد في تطبيق حقيقي. بالطبع ، لاستخدام التعليمات البرمجية من المثال ، تحتاج إلى إضافة معالجة الأخطاء العادية.
من المريح طلب رفع الامتيازات عند تثبيت البرنامج ، باستخدام InnoSetup ، من السهل القيام بذلك ، وتمرير السمة اللازمة في أول تشغيل للبرنامج. أيضًا ، قبل التثبيت ، من الملائم التحقق من وجود .NET 4 وتثبيته إذا لم يكن مثبتًا.
لا يوجد أحد في Virustotal يتفاعل مع هذا البرنامج ، ولكن أود أن! ولكن إذا قمت بتجميع حزمة التثبيت في InnoSetup ، يبدأ عدد من برامج مكافحة الفيروسات من المستوى الثالث بالعمل عليها. هذا يساعد في التخلص من المثبت المثبت مع شهادة توقيع التعليمات البرمجية.
التحديث التلقائي للبرنامج هنا وراء الكواليس ، لكنه بالتأكيد لن يكون لزوم له في تطبيق حقيقي. السنجاب مناسب تمامًا لإدارة التحديثات التلقائية. من المريح أيضًا استخدام السنجاب لإزالة شهاداتنا من النظام عند حذف البرنامج.
رمز عينة نشر على جيثب .
شكرا لاهتمامكم!