مقدمة
نظرًا لأن Angular عبارة عن تطبيق من صفحة واحدة ، سيتم تحميل معظم الموارد في المتصفح من البداية ، لذلك تحتاج إلى إيلاء المزيد من الاهتمام لتوقيت التحقق والتأكد من أن المستخدمين الذين اجتازوا فقط يمكنهم رؤية الواجهة المقابلة.
تشير المصادقة في هذه المقالة إلى كيفية تحديد ما إذا كان المستخدم قد قام بتسجيل الدخول والتأكد من أنه يمكن تلبية احتياجات التحقق من الخادم في كل اتصال مع الخادم. لاحظ أنه لا يشمل الحكم على ما إذا كانت هناك سلطة محددة.
بالنسبة لتسجيل الدخول ، يكون من المقرر أن يقبل اسم المستخدم وإدخال كلمة المرور للمستخدم ، وإرساله إلى الخادم للتحقق منه ، ومعالجة استجابة التحقق ، وبناء بيانات المصادقة على جانب المتصفح .
طريقتان لتنفيذ مصادقة الهوية
في الوقت الحاضر ، هناك فئتان رئيسيتان من الأساليب لتنفيذ مصادقة الهوية:
ملفات تعريف الارتباط
تستخدم صفحات الويب التقليدية للمستعرضات ملفات تعريف الارتباط للتحقق من الهوية. في الواقع ، في طبقة تطبيق المتصفح ، لا داعي للقلق بشأن التحقق من الهوية. يتم الانتهاء من إعدادات ملفات تعريف الارتباط بواسطة الخادم. عند إرسال الطلب ، يقوم المتصفح تلقائيًا بإرفاق معلومات ملفات تعريف الارتباط المقابلة. لذلك ، في رمز JavaScript ، ليست هناك حاجة لكتابة رمز خاص لهذا. لكن في كل مرة أطلبها ، سأحضر جميع بيانات ملفات تعريف الارتباط.
مع تطبيق CDN والارتفاع التدريجي للأجهزة المحمولة ، فإن ملفات تعريف الارتباط غير قادرة بشكل متزايد على تلبية احتياجات المصادقة المعقدة متعددة المجالات.
مفتاح
في الواقع ، لم تظهر المصادقة القائمة على المفاتيح مؤخرًا ، بل كانت موجودة ، حتى أطول من تاريخ ملفات تعريف الارتباط. عندما يطلب المتصفح الخادم ، يرفق المفتاح بالطلب بطريقة محددة ، كما هو الحال في رؤوس الطلب. للقيام بذلك ، يلزم كتابة رمز العميل الخاص للإدارة.
يعد معيار مفتاح الويب الناشئ (JSON Web Token) الناشئ مؤخراً مصادقة نموذجية باستخدام مفتاح.
في تطبيقات الويب ، إذا كنت تقوم ببناء واجهات برمجة التطبيقات ، فيجب أن تعطي الأولوية لاستخدام طريقة المفتاح.
عملية تسجيل الدخول
تسجيل الدخول هو الخطوة الأولى في التحقق من الهوية. فقط عن طريق تسجيل الدخول يمكن تنظيم بيانات التحقق من الهوية المقابلة.
هل تحتاج إلى استخدام صفحة تسجيل دخول منفصلة؟
هناك طريقتان للتعامل مع صفحات تسجيل الدخول:
ستقفز صفحة تسجيل دخول منفصلة إلى تطبيق صفحة واحدة بعد اكتمال تسجيل الدخول. يتيح ذلك التحكم في الوصول إلى موارد تطبيق صفحة واحدة لمنع المستخدمين من غير اللوجينات من الوصول ، وهو مناسب لسيناريوهات التطبيق لأدوات الخلفية أو الإدارة. لكنه يقلل بالفعل من تجربة المستخدم للتطبيقات ذات الصفحة الواحدة
قم بتنفيذ تسجيل الدخول داخل تطبيق صفحة واحدة ، والذي يتماشى أكثر مع مفهوم التصميم لتطبيق صفحة واحدة وأكثر ملاءمة لسيناريوهات المنتج الشائعة ، لأن الأشخاص الخبيثين يمكنهم دائمًا الحصول على الكود الأمامي لتطبيق الصفحة الواحدة.
صفحة تسجيل دخول منفصلة
بشكل عام ، فإن الغرض من استخدام صفحة تسجيل دخول منفصلة هو حماية الصفحات التي يتم القفز بعد تسجيل الدخول من الوصول من قبل المستخدمين المجهولين. لذلك ، في صفحة تسجيل الدخول ، يتم إنشاء نموذج ، ويتم استخدام طريقة تقديم الثناء التقليدية (غير AJAX) مباشرة. بعد صحة الواجهة الخلفية مع اسم المستخدم وكلمة المرور بنجاح ، يتم إخراج HTML من صفحة التطبيق الواحد بعد تسجيل الدخول.
في هذه الحالة ، يمكنك وضع معلومات المصادقة مباشرة في HTML ، على سبيل المثال ، يمكنك استخدام Jade لإنشاء صفحة مثل هذا:
<!-Dashboard.jade-> DOCTYPE HTMLHTMLHTML HEAD LINK (REL = "STYLESHEET" ، Href = "/Assets/App.E1C2C6EA9350869264DA10DE799DCED1.CSS"). window.token =! {json.stringify (token)} ؛ Div.MD-Padding (UI-View) البرنامج النصي (src = "/assets/app.84b1e53df1b4b23171da.js")بعد نجاح اسم المستخدم وكلمة المرور ، يمكن للواجهة الخلفية استخدام الطريقة التالية لتقديم وإخراج HTML:
Return Res.Render ('Dashboard' ، {token: token}) ؛بمجرد إطلاق التطبيق الزاوي ، يمكنه التواصل مع المصادقة. كما يضمن أن المستخدمين الذين قاموا بتسجيل الدخول بنجاح يمكنهم إدخال هذه الصفحة.
المنظمات التي تسجل الدخول إلى تطبيق صفحة واحدة
للتطبيقات الزاوية متعددة الرؤية ، يتم استخدام التوجيه بشكل عام. داخل الصفحة ، توجد بشكل عام قائمة شريط جانبي ثابت أو قائمة تنقل أعلى ، ويتم التحكم في منطقة النص بواسطة وحدة التوجيه.
يستخدم رمز العينة التالي مادة Angular لتنظيم الصفحة ، وتستخدم وحدة التوجيه واجهة المستخدم. عند فتح التطبيق ، هناك رسوم متحركة خاصة تحميل. بعد اكتمال التحميل ، يتم استخدام الصفحة المعروضة بواسطة وحدة تحكم AppController . للمستخدمين الذين لم يتم تسجيل الدخول ، سيتم عرض نموذج تسجيل الدخول. بعد اكتمال تسجيل الدخول ، تنقسم الصفحة إلى ثلاثة أجزاء: أحدهما هو الملاحة العليا للخبز ، والثاني هو قائمة الشريط الجانبي ، والآخر هو الجزء الرئيسي من التحكم في المسار .
الرمز كما يلي:
<body ng-app = "app" layout = "row"> <div id = "loading"> <!-page loading perfer-> </viv> <div flex layout = "row" ng-cloak ng-controller = "AppController" ng-init = "load () <!-logInform-> </viv> <div ng-if = "isuserauth" flex layout = "row"> <md-sidenav flex = "15" md-is-is-open-open = "true" </md-toolbar> <md-content> <!-التوجيه-> <div ui-view> </viv> </md-content> </md-content> </viv> </viv> </body>
لتحميل الرسوم المتحركة ، فهي خارج AppController ويمكن إخفاؤها في رمز AppController . هذا يحقق الغرض من التحميل اختفاء بعد تحميل جميع CSS/JavaScript.
هناك متغير في AppController isUserAuth يكون false عند تهيئته. عندما تكون معلومات الجلسة المخزنة محليًا صالحة ، أو بعد اكتمال تسجيل الدخول ، سيتم تعيين هذه القيمة على ture . نظرًا للتحكم في ng-if ، يمكن تحقيق الغرض من إخفاء نموذج تسجيل الدخول وعرض محتوى التطبيق. تجدر الإشارة إلى أنه فقط باستخدام ng-if بدلاً من ng-show/ng-hide هنا ، فإن الأول سيحذف عناصر DOM ويضيفه حقًا ، في حين أن الأخير سيعدل فقط سمات CSS لعنصر DOM. هذا مهم جدا. بهذه الطريقة فقط يمكننا التأكد من أنه بعد تسجيل الدخول ، سيتم تحميل المحتوى الموجود في تطبيق الصفحة الواحدة لمنع رمز وحدة التحكم في المسار الحالي من تنفيذها مباشرة قبل تسجيل الدخول.
لماذا يقوم العملاء أيضًا بتشفير كلمات المرور
إن عملية تسجيل الدخول المثالية على أساس اسم المستخدم وكلمة المرور هي كما يلي:
1 md5(username + md5(md5(password)))
2. الحضانة الخلفية تحصل على الملح المقابل استنادًا إلى اسم المستخدم ، ويستخدم اسم المستخدم وقيمة تجزئة كلمة المرور ، ويحسب نص مشفر ، ويبحث في قاعدة البيانات بناءً على اسم المستخدم وكلمة المرور
3. إذا كان الاستعلام ناجحًا ، فقم بإنشاء المفتاح ، وأعوده إلى المتصفح ، وأداء الخطوة 4
4. وتوليد الخلفية ملحًا جديدًا ، ويولد نصًا مشفرًا جديدًا يعتمد على الملح الجديد وقيمة تجزئة كلمة المرور المقدمة من المتصفح. تحديث الملح والنص المشفر في قاعدة البيانات
ربما لا يستطيع 80 ٪ من الناس فهم سبب تعقيد تسجيل الدخول. قد يتطلب هذا مقالًا خاصًا لشرحه بوضوح. هنا سأشرح أولاً سبب وجود كلمة مرور المتصفح ، والأسباب على النحو التالي:
1. حماية كلمة مرور المستخدم من المصدر لضمان أنه فقط عن طريق القيام بسجلات رئيسية ، يمكنك الحصول على كلمة المرور الأصلية للمستخدم
2. حتى إذا تم التنصت على الشبكة ولم يتم استخدام HTTPS ، فإن كلمة المرور المسروقة هي فقط بعد التجزئة ، والتي يمكن أن تؤثر على بيانات المستخدم على هذا الخادم على الأكثر ، ولا تؤثر على مواقع الويب الأخرى التي تستخدم كلمة المرور نفسها.
3. حتى صاحب الخادم لا يمكنه الحصول على كلمة المرور الأصلية للمستخدم.
يجعل هذا النهج أكبر خطر للمستخدمين ، ويُسرق البيانات الموجودة في التطبيق الحالي. لن يتم توسيع نطاق الخسارة ، ولن تكون هناك أي مشاكل مع CSDN أو تدفقات أخرى.
تسجيل الدخول إشعار ناجح
بالنسبة لبعض التطبيقات ، لا تتطلب جميع الصفحات من المستخدمين تسجيل الدخول. قد يحتاجون فقط إلى تسجيل الدخول عند إجراء عمليات معينة. في هذه الحالة ، بعد تسجيل الدخول ، يجب إخطار التطبيق بأكمله. هذا يتيح لك استخدام وظيفة البث.
الرمز البسيط هو كما يلي:
Angular .Module ('app') .Controller ('logincontroller' ، ['$ rootscope' ، logincontroller]) ؛ وظيفة logincontroller ($ rootscope) {// دالة تسمى fettloginsuccess () {$ rootscope. $ broutcast ('user.login.sucess' ، {data) ؛ }}في وحدات التحكم الأخرى ، يمكنك الاستماع إلى هذا البث وأداء العمليات التي يجب تنفيذها بعد أن تنجح تسجيل الدخول ، مثل الحصول على قائمة أو تفاصيل:
$ scope. $ on ('user.login.success' ، function (handle ، data) {// Processing}) ؛معلومات مصادقة الهوية
بعد تسجيل الدخول بنجاح ، يقوم الخادم بإرجاع المفتاح ، ويحتاج طلبات واجهة برمجة التطبيقات اللاحقة إلى إحضار المفتاح ، ويجب أيضًا التحقق من الاستجابة التي يتم إرجاعها بواسطة الطلب ما إذا كان خطأ في بطلان معلومات الهوية. هذه السلسلة من العمل مرهقة للغاية ويجب إكمالها تلقائيًا.
يحفظ
هناك تقريبًا الطرق التالية لحفظ المفتاح:
1.Coowies: كما ذكرنا سابقًا ، لا ينصح بذلك. في الوقت نفسه ، فإنه يحتوي أيضًا على حد أقصى قدره 4K
2.SessionStorage: صفحة علامة التبويب صالحة. بمجرد فتح صفحة علامة تبويب جديدة ، لا يمكن مشاركة SessionStorage.
3.LocalStorage: طريقة تخزين مثالية. ما لم يتم تنظيف بيانات المتصفح ، فإن البيانات المخزنة في LocalStorage ستكون موجودة دائمًا.
4. خدمة Singleton Angular: إذا تم تخزينها في التطبيق ، فسيتم فقد البيانات بعد تحديثها ، وبالطبع ، لا يمكن مشاركتها بين صفحات علامة التبويب.
يتمثل الطريقة الأفضل في تخزين معلومات المصادقة في LocalStorage ، ولكن يتم تهيئتها إلى خدمة Angular's Singleton عندما يبدأ التطبيق.
إضافة معلومات المصادقة إلى الطلب
الغرض من معلومات مصادقة الهوية هو الإشارة إلى هوية الخادم والحصول على البيانات. لذلك ، مطلوب معلومات مصادقة إضافية في الطلب.
في التطبيقات العامة ، يتم وضع معلومات المصادقة في رؤوس الطلب. إذا قمت بتعيين الرؤوس واحدة تلو الأخرى في كل طلب ، فسيكون الأمر مستهلكًا للوقت وشاقة للغاية. يوفر $httpProvider في Angular interceptors يمكن من خلاله تحقيق معالجة موحدة لكل طلب واستجابة.
طريقة إضافة اعتراضية هي كما يلي:
Angular .Module ('app') .Config (['$ httpprovider' ، function ($ httpprovider) {$ httpprovider.Interceptors.push (httpinterceptor) ؛}]) ؛ تعريف HttpInterceptor هو كما يلي:
angular .module ('app') .factory ('httpinterceptor' ، ['$ q' ، httpinterceptor]) ؛ وظيفة httpinterceptor ($ q) {return {// قبل إصدار الطلب ، يمكن استخدامها لإضافة طلب معلومات مصادقة مختلفة: الدالة {if (localstorage.token) { } إرجاع التكوين ؛ } ، // حدث خطأ أثناء الطلب يتم إصدار requesterror: function (err) {return $ q.reject (err) ؛ } ، // استجابة الاستجابة: function (res) {return res ؛ } ، // خطأ الاستجابة الذي تم إرجاعه ، بما في ذلك عندما تُرجع الواجهة الخلفية الاستجابة ، يتم تعيين رمز حالة http لـ غير 200: function (err) {return $ q.reject (err) ؛ }} ؛}توفر المقاطعات معالجة دورة الحياة الكاملة من الطلب إلى استجابة العودة ، والتي يمكن استخدامها عمومًا للقيام بما يلي:
1. إضافة بيانات إلى الطلبات الصادرة بشكل موحد ، مثل إضافة معلومات المصادقة
2. معالجة الأخطاء الموحدة ، بما في ذلك الأخطاء عند إصدار الطلب (مثل الشبكة على جانب المتصفح غير متصل) ، والأخطاء عند إرجاع الاستجابة
3. معالجة الاستجابة الموحدة ، مثل ذاكرة التخزين المؤقت بعض البيانات ، إلخ.
4. عرض شريط التقدم طلب الطلب
في رمز المثال أعلاه ، عندما يتضمن localStorage token القيمة ، تتم إضافة قيمة token على رأس كل طلب.
الفشل والتعامل
بشكل عام ، يجب أن تضع الواجهة الخلفية رمز حالة HTTP للاستجابة إلى 401 عند فشل التحقق token ، بحيث يمكن التعامل معه بشكل موحد في responseError التقاطع:
ResponseRror: function (err) {if (-1 === err.status) {// الخادم البعيد غير مستجيب} آخر إذا (401 === err.status) {// يتم استخدام خطأ 401 عمومًا لفشل المصادقة. يعتمد ذلك على الخطأ الذي ألقاه الواجهة الخلفية عند فشل المصادقة} آخر إذا (404 === err.status) {// يقوم الخادم بإرجاع 404} إرجاع $ Q.Reject (err) ؛}لخص
في الواقع ، طالما أن رمز الحالة الذي تم إرجاعه بواسطة الخادم ليس 200 ، سيتم استدعاء responseError . هنا ، يمكن التعامل مع الخطأ بشكل موحد وعرضه.
يرتبط المحتوى أعلاه بتسجيل الدخول والتحقق من الهوية في تطبيقات التطوير الزاوي. آمل أن يكون من المفيد للجميع أن يتعلموا الزاويين.