Authentifizierung
Der häufigste Weg bei der Gestaltung von Berechtigungen ist die rollenbasierte Zugriffskontrolle von RBAC. Die Grundidee ist, dass verschiedene Berechtigungen für Systemvorgänge nicht direkt an bestimmte Benutzer gewährt werden, sondern vielmehr eine Rollensammlung zwischen dem Benutzersatz und dem Berechtigungssatz festlegen. Jede Rolle entspricht einem entsprechenden Satz von Berechtigungen.
Sobald dem Benutzer die entsprechende Rolle zugewiesen wurde, verfügt der Benutzer über alle operativen Berechtigungen für die Rolle. Der Vorteil davon ist, dass es nicht erforderlich ist, bei jedem Erstellen eines Benutzers Berechtigungen zuzuweisen, sondern nur die entsprechende Rolle des Benutzers zuzuweisen, und die Berechtigungsänderungen der Rolle sind viel geringer als die der Berechtigungsänderungen des Benutzers, wodurch die Berechtigungsverwaltung des Benutzers vereinfacht und das Systemaufwand reduziert wird.
In einer von Angular erstellten einseitigen Anwendung müssen wir einige zusätzliche Dinge tun, um eine solche Architektur zu implementieren. Aus der gesamten Projektperspektive gibt es ungefähr 3 Plätze, mit denen Front-End-Ingenieure zu tun haben.
1. UI -Verarbeitung (urteilen, ob einige Inhalte auf der Seite basierend auf den Berechtigungen des Benutzers angezeigt werden)
2. Routing -Verarbeitung (Wenn der Benutzer auf eine URL zugreift, die keine Erlaubnis zum Zugriff hat, springt er mit einer Fehlermeldung zu einer Seite).
A.
Implementierung der Zugriffsidentitätskontrolle
Zuerst müssen Sie alle Berechtigungen des aktuellen Benutzers erhalten, bevor Angular startet, und dann ist es eleganter, diese Zuordnungsbeziehung über einen Dienst zu speichern. Für die Frage, ob der Inhalt auf einer Seite gemäß den Berechtigungen der Benutzeroberfläche angezeigt wird. Nachdem wir diese verarbeitet haben, müssen wir ein zusätzliches "Berechtigungsattribut" hinzufügen, um eine Route hinzuzufügen, wenn Sie eine Route hinzufügen, und ihm einen Wert zuweisen, um anzugeben, welche Rollen mit Berechtigungen zu dieser URL springen können, und dann das RoutechangEnestart -Ereignis über Angular anhören, um zu überprüfen, ob der aktuelle Benutzer Zugriff auf diese URL hat. Schließlich wird ein HTTP -Interceptor benötigt, um zu überwachen, wenn der von einer Anforderung zurückgegebene Status 401 oder 403 beträgt. Springen Sie zur Seite zu einer Fehlereingabeaufforderung. Das ist ungefähr das, was es ist, es scheint ein bisschen zu viele zu sein, aber es ist tatsächlich sehr einfach, damit umzugehen.
Return 401, LoginCtrl ausführen, zurückgeben, 403, Führen Sie die Berechtigte aus.
Holen Sie sich die Kartierungsbeziehung der Erlaubnis, bevor Winkel läuft
Das Winkelprojekt wird über NG-App gestartet, aber in einigen Fällen hoffen wir, dass das Winkelprojekt unter unserer Kontrolle steht. In diesem Fall hoffe ich beispielsweise, alle Berechtigungszuordnungsbeziehungen des aktuell angemeldeten Benutzer zu erhalten und dann die Angular App zu starten. Glücklicherweise liefert Angular selbst diese Methode, dh Angular.bootstrap ().
var besitzlist; angular.element (document) .ready (function () {$ .get ('/api/userPermission', function (data) {promissionlist = data; Angular.bootstrap (Dokument, ['App']);});});Diejenigen, die sorgfältig lesen, stellen möglicherweise fest, dass die Verwendung von $ .get () hier verwendet wird und es gibt keinen Fehler, der JQuery anstelle von Angulars $ Resource oder $ http verwendet, da Angular zu diesem Zeitpunkt noch nicht begonnen hat und wir seine Funktion nicht verwenden können.
Verwenden Sie den obigen Code weiter, um die erhaltene Kartierungsbeziehung als globale Variable in einen Dienst zu bringen.
// app.js var app = angular.module ('MyApp', []), Berechtigungsliste; app.run (Funktion (Berechtigungen) {permissions.setPermissions (Berechtigungslist)}); angular.element (document) .ready (function () {$ .get ('/api/userPermission', function (data) {promissionlist = data; Angular.bootstrap (Dokument, ['App']);});}); // Common_Service.js Angular.module ('MyApp') .Factory ('Berechtigungen', Funktion ($ rootScope) {var besitzlist; return {setPermissions: function (berechtigungen) {prosmissionlist = permissions; $ rootscope.Nachdem wir die Berechtigungen des aktuellen Benutzers erhalten haben, archivieren wir dies in den entsprechenden Dienst und haben dann 2 weitere Dinge durchgeführt:
(1) Speichern Sie die Berechtigungen in Fabrikvariablen, damit sie immer im Gedächtnis sind und die Rolle globaler Variablen erkennen, aber den Namespace nicht verschmutzen.
(2) Sendung Ereignis über $ Broadcast, wenn sich die Berechtigungen ändern.
1. So bestimmen Sie die sichtbare und versteckte Leistung der UI -Komponente basierend auf den Berechtigungen
Hier müssen wir selbst eine Richtlinie schreiben, die Elemente basierend auf Berechtigungsbeziehungen anzeigt oder ausblendet.
<!-Wenn der Benutzer die Berechtigung bearbeiten hat, show a link-> <div has-permission = 'edit'> <a href = "/#/teurses/{{id}}/edit"> {{name}} </a> </div> <!-Wenn der Benutzer nicht bearbeitet wird. }} </div>Hier sehe ich eine ideale Situation, dass Sie den Namen des Has-Permission-Immobilienverifizierungsberechtigungsnamens übergeben können. Wenn der aktuelle Benutzer es hat, wird er angezeigt, und wenn es nein gibt, wird es versteckt.
Angular.module ('MyApp'). Richtlinie ('HaSermission', Funktion (Berechtigungen) {return {link: function (scope, element, attrs) {if (! _. isstring (attr.Haspermission)) throw "HaSermission Value muss ein Zeichenfolgen sein. {value.Slice (1) .Trim (); SCOPE.Erweitern Sie die vorherige Fabrik:
Angular.module ('MyApp') .Factory ('Berechtigungen', Funktion ($ rootScope) {var besitzlist; return {setPermissions: Funktion (Berechtigungen) {permissionlist = Berechtigungen; $ rootscope. Funktion (Element) {if (_.2. Zugriff auf Berechtigungsbasis auf der Route
Die Idee dieses Teils der Implementierung lautet wie folgt: Wenn wir eine Route definieren, fügen wir ein Berechtigungsattribut hinzu, und der Wert des Attributs sind die Berechtigungen, die wir auf die aktuelle URL zugreifen müssen. Dann hören wir immer wieder die URL -Änderungen durch das RoutechangEnTart -Ereignis. Überprüfen Sie jedes Mal, wenn wir die URL ändern, ob die zu umgeleitete URL den Bedingungen erfüllt, und entscheiden Sie dann, ob sie erfolgreich oder auf die Fehlereingabeaufforderung umgeleitet wird.
App.config (Funktion ($ routeProvider) {$ routeProvider .When ('/', {templateurl: 'Views/ViewCourse.html', Controller: 'ViewcourSeSctrl'}) .Wen ('/unauthorized', {templateurl: 'sehne'. .Wenn ('/Kurse/: id/edit', {templateurl: 'Ansichten/editCourses.html', Controller: 'editCourses', Erlaubnis: 'edit'});MainController.js oder IndexController.js (kurz gesagt, es ist der übergeordnete Schicht -Controller)
App.Controller ('mainAppctrl', Funktion ($ scope, $ location, Berechtigungen) {$ scope. });Die zuvor geschriebene HaSermission wird hier noch verwendet, und diese Dinge sind sehr wiederverwendbar. Dies wird getan. Beurteilen Sie vor jedem Ansichtsroutensprung nur, ob es die Erlaubnis hat, in den Controller des Elternbehälters zu springen.
A. HTTP -Anforderungsverarbeitung
Dies sollte relativ einfach umzugehen, und die Idee ist sehr einfach. Da Winkelanwendungen rastful -Stil -Ausreden empfehlen, ist die Verwendung des HTTP -Protokolls sehr klar. Wenn der von der Anforderung zurückgegebene Statuscode 401 oder 403 beträgt, gibt es keine Berechtigung, sodass Sie einfach zur entsprechenden Fehlereingabeaufforderung springen können.
Natürlich können wir jede Anfrage nicht manuell verifizieren und weiterleiten, daher müssen wir auf jeden Fall einen Gesamtfilter benötigen. Der Code ist wie folgt:
Angular.module ('MyApp') .Config (Funktion ($ httpprovider) {$ httpprovider.responseInterceptors.push ('SecurityInterceptor'). if (Antwort.Status === 403 ||Durch das Schreiben können Sie fast die Berechtigungsverwaltung und Kontrolle des Front-End-Teils in diesem Front-End-Trennungsmodus erkennen.
Formüberprüfung
AngularJS Front-End-Verifizierungsrichtlinie
var rcsubmitDirective = {'rcsubmit': function ($ parse) {return {prestrict: "a", erfordern: ["rcsubmit", "? var formController = null; this.setattempted = function () {this.attempted = true; }; this.setFormController = Funktion (Controller) {formController = Controller; }; this.needsAtention = function (fieldModelController) {if (! formController) return false; if (fieldModelController) {return fieldModelController. $ Invalid && (FieldModelController. } else {return FormController && FormController. $ Invalid && (FormController. }}; }, kompile: function () {return {pre: function (scope, formElement, attribute, controller) {var subjektcontroller = Controller [0]; var formController = Controller.Length> 1? Controller [1]: Null; sublecontroller.setformController (FormController); Scope.rc = Scope.rc || {}; Scope.rc [Attribute.name] = Sublecontroller; }, post: Funktion (Umfang, Formelement, Attribute, Controller) {var subjektcontroller = Controller [0]; var formController = Controller.Length> 1? Controller [1]: Null; var fn = $ parse (Attribute.rcsubmit); formElement.bind ("subjekt", Funktion (Ereignis) {sublectController.setattempted (); if (! scope. $$ phase) Scope. $ anwenden (); if (! formController. }}; }}; }}; }}; }}; }}; }}; }}; }};Überprüfung verabschiedet
<form name = "loginForm" novalidat ng-App = "loginapp" ng-controller = "logincontroller" rc-submit = "login ()"> <div ng-class = "{'Hasern-Error': RC.Loginform.NeedSattention (loginform. ng-model = "session.username"/> <span ng-show = "rc.forme type = "password" placeholder = "password" erfordert ng-model = "session.password"/> <span ng-show = "rc.form.Der Stil ist wie folgt
Login () wird nach dem Ablauf der Front-End-Überprüfung aufgerufen.