webentwicklung-frage-antwort-db.com.de

AngularJS-Authentifizierung + RESTful-API

Angular + RESTful Client-seitige Kommunikation mit API für Auth/(re) Routing

Dies wurde in einigen verschiedenen Fragen und in einigen verschiedenen Tutorials behandelt, aber all die vorherigen Ressourcen, auf die ich gestoßen bin, treffen den Nagel nicht ganz auf den Kopf.

In einer Nussschale muss ich

  • Einloggen über POST von http://client.foo Bis http://api.foo/login
  • Verfügen Sie über einen GUI-/Komponentenstatus "angemeldet" für den Benutzer, der eine Route logout bereitstellt
  • Sie können die Benutzeroberfläche "aktualisieren", wenn sich der Benutzer abmeldet/abmeldet. Das war am frustrierendsten
  • Schützen Sie meine Routen, um den Authentifizierungsstatus zu überprüfen (falls erforderlich), und leiten Sie den Benutzer entsprechend zur Anmeldeseite weiter

Meine Probleme sind

  • Jedes Mal, wenn ich zu einer anderen Seite navigiere, muss ich api.foo/status Anrufen, um festzustellen, ob ein Benutzer angemeldet ist oder nicht. (ATM Ich verwende Express für Routen.) Dies führt zu einem Schluckauf wie Angular bestimmt Dinge wie ng-show="user.is_authenticated"
  • Wenn ich mich erfolgreich an-/abgemeldet habe, muss ich die Seite aktualisieren (ich möchte dies nicht tun), um Dinge wie {{user.first_name}} Auszufüllen, oder im Falle der Abmeldung diesen Wert ausleeren .
// Sample response from `/status` if successful 

{
   customer: {...},
   is_authenticated: true,
   authentication_timeout: 1376959033,
   ...
}

Was ich ausprobiert habe

Warum ich das Gefühl habe, den Verstand zu verlieren

  • Es scheint, als ob sich jedes Tutorial auf eine Datenbanklösung stützt (viel Mongo, Couch, PHP + MySQL, ad infinitum), und keine stützt sich ausschließlich auf die Kommunikation mit einer RESTful-API, um den Anmeldestatus beizubehalten. Sobald Sie angemeldet sind, werden zusätzliche POSTs/GETs mit withCredentials:true Gesendet. Das ist also nicht das Problem
  • Ich kann KEINE Beispiele/Tutorials/Repos finden, die Angular + REST + Auth ohne Backend-Sprache ausführen.

Ich bin nicht zu stolz

Zugegeben, ich bin neu bei Angular und würde mich nicht wundern, wenn ich mich auf lächerliche Weise dem nähere. Ich würde mich freuen, wenn jemand eine Alternative vorschlägt - auch wenn es Suppe-zu-Nuss ist.

Ich benutze Express hauptsächlich, weil ich Jade und Stylus wirklich liebe - ich bin nicht mit dem Routing von Express verheiratet und werde es aufgeben, wenn Was ich tun möchte, ist nur mit Angulars Routing möglich.

Vielen Dank im Voraus für jede Hilfe, die jemand leisten kann. Und bitte frag mich nicht bei Google, da ich ungefähr 26 Seiten lila Links habe. ;-)


1Diese Lösung basiert auf Angulars $ httpBackend-Mock, und es ist unklar, wie sie mit einem echten Server kommunizieren kann.

2Dies war die naheliegendste, aber da ich eine vorhandene API habe, mit der ich mich authentifizieren muss, konnte ich Passports 'localStrategy' nicht verwenden, und es schien verrückt zu sein schreibe einen OAUTH Service ... den nur ich verwenden wollte.

71
couzzi

Dies stammt aus meinem Blogbeitrag über URL-Routenautorisierung und Elementsicherheit hier aber ich fasse die wichtigsten Punkte kurz zusammen :-)

Die Sicherheit in der Frontend-Webanwendung ist lediglich eine Startmaßnahme, um Joe Public zu stoppen. Jeder Benutzer mit etwas Webwissen kann sie jedoch umgehen, sodass Sie immer auch auf der Seite des Sicherheitsservers sein sollten.

Das Hauptanliegen im Bereich Sicherheit in angular) ist die Routensicherheit. Glücklicherweise erstellen Sie beim Definieren einer Route in angular=) ein Objekt, ein Objekt, das andere Eigenschaften haben kann Der Eckpfeiler meines Ansatzes besteht darin, diesem Routenobjekt ein Sicherheitsobjekt hinzuzufügen, das im Grunde die Rollen definiert, die der Benutzer haben muss, um auf eine bestimmte Route zugreifen zu können.

 // route which requires the user to be logged in and have the 'Admin' or 'UserManager' permission
    $routeProvider.when('/admin/users', {
        controller: 'userListCtrl',
        templateUrl: 'js/modules/admin/html/users.tmpl.html',
        access: {
            requiresLogin: true,
            requiredPermissions: ['Admin', 'UserManager'],
            permissionType: 'AtLeastOne'
        });

Der gesamte Ansatz konzentriert sich auf einen Autorisierungsdienst, der im Wesentlichen prüft, ob der Benutzer über die erforderlichen Berechtigungen verfügt. Dieser Dienst entfernt die Bedenken hinsichtlich des Benutzers und seiner tatsächlichen Berechtigung, die beim Anmelden vom Server abgerufen worden wäre, von den anderen Teilen dieser Lösung. Obwohl der Code ziemlich ausführlich ist, wird er in meinem Blog-Beitrag ausführlich erklärt. Grundsätzlich werden jedoch die Berechtigungsprüfung und zwei Berechtigungsmodi behandelt. Das erste ist, dass der Benutzer mindestens eine der definierten Berechtigungen haben muss, das zweite ist, dass der Benutzer alle definierten Berechtigungen haben muss.

angular.module(jcs.modules.auth.name).factory(jcs.modules.auth.services.authorization, [  
'authentication',  
function (authentication) {  
 var authorize = function (loginRequired, requiredPermissions, permissionCheckType) {
    var result = jcs.modules.auth.enums.authorised.authorised,
        user = authentication.getCurrentLoginUser(),
        loweredPermissions = [],
        hasPermission = true,
        permission, i;

    permissionCheckType = permissionCheckType || jcs.modules.auth.enums.permissionCheckType.atLeastOne;
    if (loginRequired === true && user === undefined) {
        result = jcs.modules.auth.enums.authorised.loginRequired;
    } else if ((loginRequired === true && user !== undefined) &&
        (requiredPermissions === undefined || requiredPermissions.length === 0)) {
        // Login is required but no specific permissions are specified.
        result = jcs.modules.auth.enums.authorised.authorised;
    } else if (requiredPermissions) {
        loweredPermissions = [];
        angular.forEach(user.permissions, function (permission) {
            loweredPermissions.Push(permission.toLowerCase());
        });

        for (i = 0; i < requiredPermissions.length; i += 1) {
            permission = requiredPermissions[i].toLowerCase();

            if (permissionCheckType === jcs.modules.auth.enums.permissionCheckType.combinationRequired) {
                hasPermission = hasPermission && loweredPermissions.indexOf(permission) > -1;
                // if all the permissions are required and hasPermission is false there is no point carrying on
                if (hasPermission === false) {
                    break;
                }
            } else if (permissionCheckType === jcs.modules.auth.enums.permissionCheckType.atLeastOne) {
                hasPermission = loweredPermissions.indexOf(permission) > -1;
                // if we only need one of the permissions and we have it there is no point carrying on
                if (hasPermission) {
                    break;
                }
            }
        }

        result = hasPermission ?
                 jcs.modules.auth.enums.authorised.authorised :
                 jcs.modules.auth.enums.authorised.notAuthorised;
    }

    return result;
};

Da eine Route nun über Sicherheit verfügt, müssen Sie bestimmen, ob ein Benutzer auf die Route zugreifen kann, wenn eine Routenänderung gestartet wurde. Dazu fangen wir die Routenänderungsanforderung ab, untersuchen das Routenobjekt (mit unserem neuen Zugriffsobjekt darauf) und ersetzen die Route durch eine andere, wenn der Benutzer nicht auf die Ansicht zugreifen kann.

angular.module(jcs.modules.auth.name).run([  
    '$rootScope',
    '$location',
    jcs.modules.auth.services.authorization,
    function ($rootScope, $location, authorization) {
        $rootScope.$on('$routeChangeStart', function (event, next) {
            var authorised;
            if (next.access !== undefined) {
                authorised = authorization.authorize(next.access.loginRequired,
                                                     next.access.permissions,
                                                     next.access.permissionCheckType);
                if (authorised === jcs.modules.auth.enums.authorised.loginRequired) {
                    $location.path(jcs.modules.auth.routes.login);
                } else if (authorised === jcs.modules.auth.enums.authorised.notAuthorised) {
                    $location.path(jcs.modules.auth.routes.notAuthorised).replace();
                }
            }
        });
    }]);

Der Schlüssel hier ist wirklich die '.replace ()', da diese die aktuelle Route (die, zu der sie keine Rechte haben) durch die Route ersetzt, zu der wir sie umleiten. Dies stoppt jedes Zurücknavigieren zu der nicht autorisierten Route.

Jetzt können wir Routen abfangen und einige coole Dinge tun, einschließlich mleiten nach einem Login wenn ein Benutzer auf einer Route gelandet ist, für die er angemeldet sein musste.

Der zweite Teil der Lösung besteht darin, das Benutzeroberflächenelement abhängig von den Rechten des Benutzers ein- und auszublenden. Dies wird durch eine einfache Anweisung erreicht.

angular.module(jcs.modules.auth.name).directive('access', [  
        jcs.modules.auth.services.authorization,
        function (authorization) {
            return {
              restrict: 'A',
              link: function (scope, element, attrs) {
                  var makeVisible = function () {
                          element.removeClass('hidden');
                      },
                      makeHidden = function () {
                          element.addClass('hidden');
                      },
                      determineVisibility = function (resetFirst) {
                          var result;
                          if (resetFirst) {
                              makeVisible();
                          }

                          result = authorization.authorize(true, roles, attrs.accessPermissionType);
                          if (result === jcs.modules.auth.enums.authorised.authorised) {
                              makeVisible();
                          } else {
                              makeHidden();
                          }
                      },
                      roles = attrs.access.split(',');


                  if (roles.length > 0) {
                      determineVisibility(true);
                  }
              }
            };
        }]);

Sie würden dann sicher ein Element wie das Folgende finden:

 <button type="button" access="CanEditUser, Admin" access-permission-type="AtLeastOne">Save User</button>

Lesen Sie mein vollständiger Blog-Beitrag für eine viel detailliertere Übersicht über die Vorgehensweise.

34
Jon

Ich habe ein AngularJS-Modul für serApp geschrieben, das so ziemlich alles macht, wonach Sie fragen. Sie können entweder:

  1. Ändern Sie das Modul und hängen Sie die Funktionen an Ihre eigene API an, oder
  2. Verwenden Sie das Modul zusammen mit der Benutzerverwaltungs-API serApp

https://github.com/userapp-io/userapp-angular

Es unterstützt geschützte/öffentliche Routen, Umleiten beim Anmelden/Abmelden, Heartbeats für Statusprüfungen, Speichern des Sitzungstokens in einem Cookie, Ereignisse usw.

Wenn Sie UserApp ausprobieren möchten, nehmen Sie am Kurs über Codecademy teil.

Hier einige Beispiele, wie es funktioniert:

  • Anmeldeformular mit Fehlerbehandlung:

    <form ua-login ua-error="error-msg">
        <input name="login" placeholder="Username"><br>
        <input name="password" placeholder="Password" type="password"><br>
        <button type="submit">Log in</button>
        <p id="error-msg"></p>
    </form>
    
  • Anmeldeformular mit Fehlerbehandlung:

    <form ua-signup ua-error="error-msg">
      <input name="first_name" placeholder="Your name"><br>
      <input name="login" ua-is-email placeholder="Email"><br>
      <input name="password" placeholder="Password" type="password"><br>
      <button type="submit">Create account</button>
      <p id="error-msg"></p>
    </form>
    
  • So legen Sie fest, welche Routen öffentlich sein sollen und welche Route das Anmeldeformular ist:

    $routeProvider.when('/login', {templateUrl: 'partials/login.html', public: true, login: true});
    $routeProvider.when('/signup', {templateUrl: 'partials/signup.html', public: true});
    

    Die Route .otherwise() sollte dahin führen, wo Ihre Benutzer nach der Anmeldung umgeleitet werden sollen. Beispiel:

    $routeProvider.otherwise({redirectTo: '/home'});

  • Link abmelden:

    <a href="#" ua-logout>Log Out</a>

    (Beendet die Sitzung und leitet zur Anmelderoute weiter.)

  • Zugriff auf Benutzereigenschaften:

    Der Zugriff auf Benutzerinformationen erfolgt über den Dienst user, z. B .: user.current.email

    Oder in der Vorlage: <span>{{ user.email }}</span>

  • Elemente ausblenden, die nur sichtbar sein sollen, wenn Sie angemeldet sind:

    <div ng-show="user.authorized">Welcome {{ user.first_name }}!</div>

  • Ein Element basierend auf Berechtigungen anzeigen:

    <div ua-has-permission="admin">You are an admin</div>

Um sich bei Ihren Back-End-Diensten zu authentifizieren, verwenden Sie einfach user.token(), um das Sitzungstoken abzurufen, und senden Sie es mit der Anforderung AJAX). Verwenden Sie im Back-End die Option - serApp API (wenn Sie UserApp verwenden), um zu überprüfen, ob das Token gültig ist oder nicht.

Wenn Sie Hilfe benötigen, lassen Sie es mich einfach wissen :)

Ich habe $ resource nicht verwendet, weil ich meine Serviceabrufe für meine Anwendung von Hand erstelle. Das heißt, ich habe die Anmeldung über einen Dienst abgewickelt, der von allen anderen Diensten abhängt, die eine Art Initialisierungsdaten erhalten. Nach erfolgreicher Anmeldung werden alle Dienste initialisiert.

In meinem Controller-Bereich beobachte ich die loginServiceInformation und fülle einige Eigenschaften des Modells entsprechend aus (um das entsprechende Ein-/Ausblenden auszulösen). In Bezug auf das Routing verwende ich Angulars eingebautes Routing und habe einfach ein ng-hide basierend auf dem hier gezeigten Booleschen Wert für "eingeloggt". Es zeigt Text zur Anforderung der Anmeldung oder das div mit dem Attribut "ng-view" (falls nicht angemeldet) sofort nach dem einloggen bist du auf der richtigen seite, momentan lade ich daten für alle ansichten aber ich glaube das könnte selektiver sein wenn nötig)

//Services
angular.module("loginModule.services", ["gardenModule.services",
                                        "surveyModule.services",
                                        "userModule.services",
                                        "cropModule.services"
                                        ]).service(
                                            'loginService',
                                            [   "$http",
                                                "$q",
                                                "gardenService",
                                                "surveyService",
                                                "userService",
                                                "cropService",
                                                function (  $http,
                                                            $q,
                                                            gardenService,
                                                            surveyService,
                                                            userService,
                                                            cropService) {

    var service = {
        loginInformation: {loggedIn:false, username: undefined, loginAttemptFailed:false, loggedInUser: {}, loadingData:false},

        getLoggedInUser:function(username, password)
        {
            service.loginInformation.loadingData = true;
            var deferred = $q.defer();

            $http.get("php/login/getLoggedInUser.php").success(function(data){
                service.loginInformation.loggedIn = true;
                service.loginInformation.loginAttemptFailed = false;
                service.loginInformation.loggedInUser = data;

                gardenService.initialize();
                surveyService.initialize();
                userService.initialize();
                cropService.initialize();

                service.loginInformation.loadingData = false;

                deferred.resolve(data);
            }).error(function(error) {
                service.loginInformation.loggedIn = false;
                deferred.reject(error);
            });

            return deferred.promise;
        },
        login:function(username, password)
        {
            var deferred = $q.defer();

            $http.post("php/login/login.php", {username:username, password:password}).success(function(data){
                service.loginInformation.loggedInUser = data;
                service.loginInformation.loggedIn = true;
                service.loginInformation.loginAttemptFailed = false;

                gardenService.initialize();
                surveyService.initialize();
                userService.initialize();
                cropService.initialize();

                deferred.resolve(data);
            }).error(function(error) {
                service.loginInformation.loggedInUser = {};
                service.loginInformation.loggedIn = false;
                service.loginInformation.loginAttemptFailed = true;
                deferred.reject(error);
            });

            return deferred.promise;
        },
        logout:function()
        {
            var deferred = $q.defer();

            $http.post("php/login/logout.php").then(function(data){
                service.loginInformation.loggedInUser = {};
                service.loginInformation.loggedIn = false;
                deferred.resolve(data);
            }, function(error) {
                service.loginInformation.loggedInUser = {};
                service.loginInformation.loggedIn = false;
                deferred.reject(error);
            });

            return deferred.promise;
        }
    };
    service.getLoggedInUser();
    return service;
}]);

//Controllers
angular.module("loginModule.controllers", ['loginModule.services']).controller("LoginCtrl", ["$scope", "$location", "loginService", function($scope, $location, loginService){

    $scope.loginModel = {
                        loadingData:true,
                        inputUsername: undefined,
                        inputPassword: undefined,
                        curLoginUrl:"partials/login/default.html",
                        loginFailed:false,
                        loginServiceInformation:{}
                        };

    $scope.login = function(username, password) {
        loginService.login(username,password).then(function(data){
            $scope.loginModel.curLoginUrl = "partials/login/logoutButton.html";
        });
    }
    $scope.logout = function(username, password) {
        loginService.logout().then(function(data){
            $scope.loginModel.curLoginUrl = "partials/login/default.html";
            $scope.loginModel.inputPassword = undefined;
            $scope.loginModel.inputUsername = undefined;
            $location.path("home");
        });
    }
    $scope.switchUser = function(username, password) {
        loginService.logout().then(function(data){
            $scope.loginModel.curLoginUrl = "partials/login/loginForm.html";
            $scope.loginModel.inputPassword = undefined;
            $scope.loginModel.inputUsername = undefined;
        });
    }
    $scope.showLoginForm = function() {
        $scope.loginModel.curLoginUrl = "partials/login/loginForm.html";
    }
    $scope.hideLoginForm = function() {
        $scope.loginModel.curLoginUrl = "partials/login/default.html";
    }

    $scope.$watch(function(){return loginService.loginInformation}, function(newVal) {
        $scope.loginModel.loginServiceInformation = newVal;
        if(newVal.loggedIn)
        {
            $scope.loginModel.curLoginUrl = "partials/login/logoutButton.html";
        }
    }, true);
}]);

angular.module("loginModule", ["loginModule.services", "loginModule.controllers"]);

Das HTML

<div style="height:40px;z-index:200;position:relative">
    <div class="well">
        <form
            ng-submit="login(loginModel.inputUsername, loginModel.inputPassword)">
            <input
                type="text"
                ng-model="loginModel.inputUsername"
                placeholder="Username"/><br/>
            <input
                type="password"
                ng-model="loginModel.inputPassword"
                placeholder="Password"/><br/>
            <button
                class="btn btn-primary">Submit</button>
            <button
                class="btn"
                ng-click="hideLoginForm()">Cancel</button>
        </form>
        <div
            ng-show="loginModel.loginServiceInformation.loginAttemptFailed">
            Login attempt failed
        </div>
    </div>
</div>

Das Basis-HTML, das die obigen Teile verwendet, um das Bild zu vervollständigen:

<body ng-controller="NavigationCtrl" ng-init="initialize()">
        <div id="outerContainer" ng-controller="LoginCtrl">
            <div style="height:20px"></div>
            <ng-include src="'partials/header.html'"></ng-include>
            <div  id="contentRegion">
                <div ng-hide="loginModel.loginServiceInformation.loggedIn">Please login to continue.
                <br/><br/>
                This new version of this site is currently under construction.
                <br/><br/>
                If you need the legacy site and database <a href="legacy/">click here.</a></div>
                <div ng-view ng-show="loginModel.loginServiceInformation.loggedIn"></div>
            </div>
            <div class="clear"></div>
            <ng-include src="'partials/footer.html'"></ng-include>
        </div>
    </body>

Ich habe den Login-Controller mit einem ng-Controller weiter oben im DOM definiert, damit ich den Body-Bereich meiner Seite basierend auf der loggedIn-Variablen ändern kann.

Hinweis Ich habe die Formularüberprüfung hier noch nicht implementiert. Zugegebenermaßen immer noch recht frisch zu Angular also sind alle Hinweise auf Dinge in diesem Beitrag willkommen. Obwohl dies die Frage nicht direkt beantwortet, da es sich nicht um eine REST-basierte Implementierung handelt, glaube ich, dasselbe kann an $ resources angepasst werden, da es auf $ http-Aufrufen aufbaut.

4
shaunhusain

Ich habe ein Github-Repo erstellt, das diesen Artikel im Wesentlichen zusammenfasst: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec

ng-login Github repo

Plunker

Ich werde versuchen, es so gut wie möglich zu erklären, hoffe, ich helfe einigen von euch da draußen:

(1) app.js: Erstellung von Authentifizierungskonstanten in der App-Definition

var loginApp = angular.module('loginApp', ['ui.router', 'ui.bootstrap'])
/*Constants regarding user login defined here*/
.constant('USER_ROLES', {
    all : '*',
    admin : 'admin',
    editor : 'editor',
    guest : 'guest'
}).constant('AUTH_EVENTS', {
    loginSuccess : 'auth-login-success',
    loginFailed : 'auth-login-failed',
    logoutSuccess : 'auth-logout-success',
    sessionTimeout : 'auth-session-timeout',
    notAuthenticated : 'auth-not-authenticated',
    notAuthorized : 'auth-not-authorized'
})

(2) Auth Service: Alle folgenden Funktionen sind im auth.js Service implementiert. Der $ http-Dienst wird zur Kommunikation mit dem Server für die Authentifizierungsverfahren verwendet. Enthält auch Funktionen zur Autorisierung, dh wenn der Benutzer eine bestimmte Aktion ausführen darf.

angular.module('loginApp')
.factory('Auth', [ '$http', '$rootScope', '$window', 'Session', 'AUTH_EVENTS', 
function($http, $rootScope, $window, Session, AUTH_EVENTS) {

authService.login() = [...]
authService.isAuthenticated() = [...]
authService.isAuthorized() = [...]
authService.logout() = [...]

return authService;
} ]);

(3) Sitzung: Ein Singleton zum Speichern von Benutzerdaten. Die Umsetzung hier hängt von Ihnen ab.

angular.module('loginApp').service('Session', function($rootScope, USER_ROLES) {

    this.create = function(user) {
        this.user = user;
        this.userRole = user.userRole;
    };
    this.destroy = function() {
        this.user = null;
        this.userRole = null;
    };
    return this;
});

(4) Übergeordneter Controller: Betrachten Sie dies als die "Haupt" -Funktion Ihrer Anwendung, alle Controller erben von diesem Controller und es ist das Rückgrat der Authentifizierung dieser App.

<body ng-controller="ParentController">
[...]
</body>

(5) Zugriffskontrolle: Um den Zugriff auf bestimmten Routen zu verweigern, müssen 2 Schritte ausgeführt werden:

a) Fügen Sie im $ stateProvider-Dienst des ui-Routers die Daten der Rollen hinzu, die für den Zugriff auf die einzelnen Routen zugelassen sind (siehe unten). Dies gilt auch für ngRoute.

.config(function ($stateProvider, USER_ROLES) {
  $stateProvider.state('dashboard', {
    url: '/dashboard',
    templateUrl: 'dashboard/index.html',
    data: {
      authorizedRoles: [USER_ROLES.admin, USER_ROLES.editor]
    }
  });
})

b) Fügen Sie unter $ rootScope. $ on ('$ stateChangeStart') die Funktion hinzu, um eine Statusänderung zu verhindern, wenn der Benutzer nicht autorisiert ist.

$rootScope.$on('$stateChangeStart', function (event, next) {
    var authorizedRoles = next.data.authorizedRoles;
    if (!Auth.isAuthorized(authorizedRoles)) {
      event.preventDefault();
      if (Auth.isAuthenticated()) {
        // user is not allowed
        $rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
      } else {d
        // user is not logged in
        $rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
      }
    }
});

(6) Auth Interceptor: Dies ist implementiert, kann jedoch nicht auf den Umfang dieses Codes überprüft werden. Nach jeder $ http-Anforderung überprüft dieser Interceptor den Statuscode. Wenn einer der folgenden Werte zurückgegeben wird, sendet er ein Ereignis, um den Benutzer zu zwingen, sich erneut anzumelden.

angular.module('loginApp')
.factory('AuthInterceptor', [ '$rootScope', '$q', 'Session', 'AUTH_EVENTS',
function($rootScope, $q, Session, AUTH_EVENTS) {
    return {
        responseError : function(response) {
            $rootScope.$broadcast({
                401 : AUTH_EVENTS.notAuthenticated,
                403 : AUTH_EVENTS.notAuthorized,
                419 : AUTH_EVENTS.sessionTimeout,
                440 : AUTH_EVENTS.sessionTimeout
            }[response.status], response);
            return $q.reject(response);
        }
    };
} ]);

P.S Ein Fehler mit dem automatischen Ausfüllen von Formulardaten, wie im ersten Artikel angegeben, kann leicht vermieden werden, indem die Direktive hinzugefügt wird, die in directives.js enthalten ist.

P.S.2 Dieser Code kann vom Benutzer leicht geändert werden, um verschiedene Routen anzuzeigen oder Inhalte anzuzeigen, die nicht angezeigt werden sollten. Die Logik MUSS serverseitig implementiert werden. Dies ist nur eine Möglichkeit, die Dinge auf Ihrer ng-App richtig darzustellen.

4