المصادقة
الطريقة الأكثر شيوعًا في تصميم الأذونات هي التحكم القائم على دور RBAC. الفكرة الأساسية هي أن الأذونات المختلفة لعمليات النظام لا يتم منحها مباشرة لمستخدمي معينين ، بل إنشاء مجموعة الأدوار بين مجموعة المستخدم ومجموعة الإذن. كل دور يتوافق مع مجموعة مقابلة من الأذونات.
بمجرد تعيين المستخدم للدور المناسب ، يكون لدى المستخدم جميع الأذونات التشغيلية لهذا الدور. ميزة ذلك هي أنه لا توجد حاجة لتعيين أذونات في كل مرة يتم فيها إنشاء مستخدم ، فقط تعيين الدور المقابل للمستخدم ، وأن تغييرات إذن الدور أقل بكثير من تغييرات إذن المستخدم ، مما سيؤدي إلى تبسيط إدارة إذن المستخدم وتقليل النفقات العامة للنظام.
في تطبيق من صفحة واحدة مصممة بواسطة Angular ، نحتاج إلى القيام ببعض الأشياء الإضافية لتنفيذ مثل هذه الهندسة المعمارية. من منظور المشروع العام ، هناك حوالي 3 أماكن يحتاج المهندسون الأماميون إلى التعامل معها.
1. معالجة واجهة المستخدم (الحكم على ما إذا كان يتم عرض بعض المحتوى على الصفحة بناءً على الأذونات المملوكة للمستخدم)
2. معالجة التوجيه (عندما يصل المستخدم إلى عنوان URL الذي لا يحتوي على إذن للوصول ، فإنه يقفز إلى صفحة مع رسالة خطأ)
3. معالجة طلب HTTP (عندما نرسل طلب بيانات ، إذا كانت الحالة التي تم إرجاعها هي 401 أو 403 ، فعادة ما يتم إعادة توجيهها إلى صفحة مع رسالة خطأ)
تنفيذ التحكم في هوية الوصول
أولاً ، تحتاج إلى الحصول على جميع أذونات المستخدم الحالي قبل بدء Angular ، ثم الطريقة الأكثر أناقة هي تخزين علاقة التعيين هذه من خلال الخدمة. لما إذا كان يتم عرض المحتوى الموجود على الصفحة وفقًا لأذونات واجهة المستخدم. بعد معالجتها ، نحتاج إلى إضافة سمة "إذن" إضافي لإضافة مسار عند إضافة مسار ، وتعيينها قيمة للإشارة إلى الأدوار ذات الأذونات التي يمكن أن تقفز إلى عنوان URL هذا ، ثم الاستماع إلى حدث Routechangestart من خلال Angular للتحقق من إمكانية الوصول إلى URL هذا. أخيرًا ، هناك حاجة إلى اعتراض HTTP لمراقبة عندما تكون الحالة التي يتم إرجاعها بناءً على طلب 401 أو 403 ، تقفز إلى الصفحة إلى صفحة موجه خطأ. هذا هو ما هو عليه تقريبًا ، يبدو أنه كثير جدًا ، لكن من السهل جدًا التعامل معه.
إرجاع 401 ، تنفيذ LoginCtrl ، إرجاع 403 ، تنفيذ إذن.
احصل على علاقة تعيين الإذن قبل تشغيل الزاوي
بدأ المشروع الزاوي من خلال تطبيق NG-APP ، لكن في بعض الحالات نأمل أن يكون المشروع الزاوي تحت سيطرتنا. على سبيل المثال ، في هذه الحالة ، آمل أن أحصل على جميع علاقات تعيين الإذن للمستخدم الذي تم تسجيله حاليًا ثم بدء التطبيق الزاوي. لحسن الحظ ، توفر Angular نفسها هذه الطريقة ، أي Angular.Bootstrap ().
VAR Angular.Element (document) .Ready (function () {$ .get ('/api/userpermission' ، function (data) {semrissionList = data ؛ Angular.Bootstrap (document ، ['app']) ؛}) ؛}) ؛قد يلاحظ أولئك الذين يقرؤون بعناية أن استخدام $ .get () يستخدم هنا ، ولا يوجد خطأ باستخدام jQuery بدلاً من مورد Angular $ أو $ HTTP ، لأنه في هذا الوقت ، لم يبدأ Angular بعد ، ولا يمكننا استخدام وظيفته.
مزيد من استخدام الكود أعلاه لوضع علاقة التعيين التي تم الحصول عليها في خدمة كمتغير عالمي.
// app.js var app = Angular.Module ('myapp' ، []) ، SemissionList ؛ app.run (function (أذونات) {أذونات. Angular.Element (document) .Ready (function () {$ .get ('/api/userpermission' ، function (data) {semrissionList = data ؛ Angular.Bootstrap (document ، ['app']) ؛}) ؛}) ؛ // common_service.js Angular.Module ('myapp') .Factory ('أذونات' ، الدالة ($ rootscope) {var repremissionlist ؛ return {setPermissions: functions (أذونات) {premrissionlist = إذن ؛ $ rootscope. $ broadcast ('PermisionsChanged')}}}}) ؛بعد الحصول على مجموعة الأذونات من المستخدم الحالي ، نرشفة هذه المجموعة في الخدمة المقابلة ، ثم نفعل شيئين آخرين:
(1) تخزين أذونات في متغيرات المصنع بحيث تكون دائمًا في الذاكرة ، وتحقق دور المتغيرات العالمية ، ولكن لا تلوث مساحة الاسم.
(2) الحدث البث من خلال البث $ ، عندما تتغير الأذونات.
1. كيفية تحديد القوة المرئية والمخفية لمكون واجهة المستخدم بناءً على الأذونات
نحتاج هنا إلى كتابة توجيهات أنفسنا ، والتي ستعرض أو إخفاء العناصر بناءً على علاقات الإذن.
<!-إذا كان المستخدم قد قام بتحرير إذن ، فإن إظهار الرابط-> <div has-permission = 'edit'> <a href = "/#/jouses/{{id}}/edit"> {{name}} </a> </iv> <! {{name}} </div>هنا أرى موقفًا مثاليًا يمكنك تمرير اسم إذن التحقق من خاصية HAS-Serming ، وإذا كان المستخدم الحالي قد تم عرضه ، فسيتم عرضه ، وإذا لم يكن هناك ، فسيتم إخفاؤه.
Angular.Module ('myapp'). التوجيه ('haspermission' ، الدالة (أذونات) {return {link: function (scope ، element ، attrs) {if (! {value.slice (1) .trim () ؛ Scope. $ على ("أذونات" ، ToggleVisableBased Mission) ؛قم بتوسيع المصنع السابق:
Angular.Module ('myapp') .factory ('أذونات' ، الدالة ($ rootscope) {var semorssistlist ؛ return {setPermissions: function (أذونات) {إذن قائمة = الأذلام ؛ $ rootscope. الدالة (البند) {if (_. istring (item.name)) item.name.trim () === SERMISSE}) ؛2. الوصول القائم على الإذن على الطريق
فكرة هذا الجزء من التنفيذ هي كما يلي: عندما نحدد المسار ، نضيف سمة إذن ، وقيمة السمة هي ما هي الأذونات التي لدينا للوصول إلى عنوان URL الحالي. ثم ، نستمر في الاستماع إلى تغيير عنوان URL من خلال حدث Routechangestart. في كل مرة نقوم فيها بتغيير عنوان URL ، تحقق مما إذا كان عنوان URL الذي سيتم إعادة توجيهه يفي بالشروط ، ثم نقرر ما إذا كان سيتم إعادة توجيهه بنجاح أو إلى صفحة موجه الخطأ.
app.config (function ($ routeprovider) {$ routeprovider. when ('/' ، {templateurl: 'views/viewCourses.html' ، controller: 'ViewCoursesctrl'}). .MainController.js أو IndexController.js (باختصار ، هو وحدة تحكم الطبقة الأم)
App.Controller ('mainappctrl' ، function ($ scope ، $ location ، أذونات) {$ scope. $ on ('$ routechangestart' ، function (scope ، next ، current) {var premrission = next. $$ route.permission ؛ if (_. istring (الإذن) &&! }) ؛لا يزال هناك استخدام Haspermission من قبل هنا ، وهذه الأشياء قابلة لإعادة الاستخدام للغاية. يتم ذلك. قبل كل عرض قفزة مسار ، فقط احكم على ما إذا كان لديه إذن للقفز في وحدة تحكم الحاوية الأصل.
3. معالجة طلب HTTP
يجب أن يكون هذا سهلاً نسبياً للتعامل معه ، والفكرة بسيطة للغاية. نظرًا لأن التطبيقات الزاوية توصي بأعذار نمط مريحة ، فإن استخدام بروتوكول HTTP واضح للغاية. إذا كان رمز الحالة الذي تم إرجاعه بواسطة الطلب هو 401 أو 403 ، فهذا يعني أنه لا يوجد إذن ، بحيث يمكنك فقط الانتقال إلى صفحة مطالبة الخطأ المقابلة.
بالطبع ، لا يمكننا التحقق يدويًا وإعادة توجيه كل طلب مرة واحدة ، لذلك يجب أن نحتاج بالتأكيد إلى مرشح كامل. الرمز كما يلي:
Angular.Module ('myapp') .Config (function ($ httpprovider) {$ httpprovider.responseInterceptors.push ('SecurityInterceptor') ؛}) .provider ('securityIntroptor' ، function () {this. $ get ($ location ، $ q) if (status === 403من خلال كتابة هذا ، يمكنك تقريبًا إدراك إدارة الإذن والتحكم في الجزء الأمامي في وضع الفصل الأمامي هذا.
التحقق من النموذج
توجيه التحقق من الواجهة الأمامية AngularJS
var rcsubmitdiRective = {'rcsubmit': function ($ parse) {return {restrict: "a" ، reques: ["rcsubmit" ، "؟؟ form"] ، controller: function () {this.attempted = false ؛ var formController = null ؛ this.setattempted = function () {this.attempted = true ؛ } ؛ this.setFormController = function (controller) {formController = controller ؛ } ؛ this.needsattention = function (fieldModelController) {if (! formController) return false ؛ if (fieldModelController) {return fieldModElController. $ invalid && (fieldModelController. $ dirty || this.attempted) ؛ } else {return formController && formController. $ invalid && (formController. $ dirty || this.attempted) ؛ }} ؛ } ، compile: function () {return {pre: function (scope ، formelement ، entributes ، controllers) {var surffController = controllers [0] ؛ var formController = controllers.length> 1؟ وحدات التحكم [1]: لاغية ؛ إرسال controller.setFormController (FormController) ؛ scope.rc = scope.rc || {} ؛ Scope.rc [attributes.name] = submitController ؛ } ، post: function (scope ، formelement ، entributes ، controllers) {var submitController = controllers [0] ؛ var formController = controllers.length> 1؟ وحدات التحكم [1]: لاغية ؛ var fn = $ parse (attributes.rcsubmit) ؛ formelement.bind ("submit" ، function (event) {submitController.setattempted () ؛ if (! scope. $ $ phase) scope. $ application () ؛ if (! formController. $ صالحة) }} ؛ }} ؛ }} ؛ }} ؛ }} ؛ }} ؛ }} ؛ }} ؛ }} ؛لقد مرت التحقق
<form name = "logInform" novalidate ng-app = "loginapp" ng-controller = "logincontroller" rc-submit = "login ()> <div ng-class =" {'has-error': useRor ': rc.loginform.needsattention (loginform.username)} ng-model = "session.username"/> <span ng-show = "rc.form.needsattention (loginform.username) && loginform.username. $ error.required"> مطلوب </span> </div> <div ng-class = "{'has-error': rc.loginform.needsatte (loginforte) type = "password" placeholder = "password" مطلوب ng-model = "session.password"/> <span ng-show = "rc.form.needsattention (loginform.password) && loginform.password. $ error> regin> required"> مطلوب </span> </span> <div> <div>النمط كما يلي
سيتم استدعاء تسجيل الدخول () بعد مرور التحقق الأمامي.