Eine Lösung besteht darin, ein 'notAuthorized'-Ereignis zu senden und es im Hauptbereich abzufangen, um den Speicherort erneut zu ändern. Ich denke, es ist nicht die beste Lösung, aber es hat bei mir funktioniert:
myApp.run(['$rootScope', 'LoginService',
function ($rootScope, LoginService) {
$rootScope.$on('$routeChangeStart', function (event, next, current) {
var authorizedRoles = next.data ? next.data.authorizedRoles : null;
if (LoginService.isAuthenticated()) {
if (!LoginService.isAuthorized(authorizedRoles)) {
$rootScope.$broadcast('notAuthorized');
}
}
});
}
]);
und in meinem Hauptcontroller:
$scope.$on('notAuthorized', function(){
$location.path('/forbidden');
});
Hinweis: Es gibt einige Diskussionen zu diesem Problem auf einer eckigen Website, die noch nicht gelöst ist:
https://github.com/angular/angular.js/pull/4192
BEARBEITEN:
Um den Kommentar zu beantworten, finden Sie hier weitere Informationen zu den Funktionen von LoginService. Es enthält 3 Funktionen:
- login () (Name ist irreführend) fordert den Server auf, Informationen über den (zuvor) angemeldeten Benutzer abzurufen. Es gibt eine weitere Anmeldeseite, auf der nur der aktuelle Benutzerstatus auf dem Server ausgefüllt wird (mithilfe des SpringSecurity-Frameworks). Meine Webdienste sind nicht wirklich zustandslos, aber ich habe es vorgezogen, dass dieses berühmte Framework meine Sicherheit übernimmt.
- isAuthenticated () sucht nur, ob die Client-Sitzung mit Daten gefüllt ist, was bedeutet, dass sie vor (*) authentifiziert wurde.
- isAuthorized () behandelte Zugriffsrechte (außerhalb des Bereichs für dieses Thema).
(*) Meine Sitzung wird ausgefüllt, wenn sich die Route ändert. Ich habe dann die when () -Methode überschrieben, um die Sitzung zu füllen, wenn sie leer ist.
Hier ist der Code:
services.factory('LoginService', ['$http', 'Session', '$q',
function($http, Session, $q){
return {
login: function () {
var defer = $q.defer();
$http({method: 'GET', url: restBaseUrl + '/currentUser'})
.success(function (data) {
defer.resolve(data);
});
return defer.promise;
},
isAuthenticated: function () {
return !!Session.userLogin;
},
isAuthorized: function (authorizedRoles) {
if (!angular.isArray(authorizedRoles)) {
authorizedRoles = [authorizedRoles];
}
return (this.isAuthenticated() && authorizedRoles.indexOf(Session.userRole) !== -1);
}
};
}]);
myApp.service('Session', ['$rootScope',
this.create = function (userId,userLogin, userRole, userMail, userName, userLastName, userLanguage) {
//User info
this.userId = userId;
this.userLogin = userLogin;
this.userRole = userRole;
this.userMail = userMail;
this.userName = userName;
this.userLastName = userLastName;
this.userLanguage = userLanguage;
};
this.destroy = function () {
this.userId = null;
this.userLogin = null;
this.userRole = null;
this.userMail = null;
this.userName = null;
this.userLastName = null;
this.userLanguage = null;
sessionStorage.clear();
};
return this;
}]);
myApp.config(['$routeProvider', 'USER_ROLES', function ($routeProvider, USER_ROLES) {
$routeProvider.accessWhen = function (path, route) {
if (route.resolve == null) {
route.resolve = {
user: ['LoginService','Session',function (LoginService, Session) {
if (!LoginService.isAuthenticated())
return LoginService.login().then(function (data) {
Session.create(data.id, data.login, data.role, data.email, data.firstName, data.lastName, data.language);
return data;
});
}]
}
} else {
for (key in route.resolve) {
var func = route.resolve[key];
route.resolve[key] = ['LoginService','Session','$injector',function (LoginService, Session, $injector) {
if (!LoginService.isAuthenticated())
return LoginService.login().then(function (data) {
Session.create(data.id, data.login, data.role, data.email, data.firstName, data.lastName, data.language);
return func(Session, $injector);
});
else
return func(Session, $injector);
}];
}
}
return $routeProvider.when(path, route);
};
//use accessWhen instead of when
$routeProvider.
accessWhen('/home', {
templateUrl: 'partials/dashboard.html',
controller: 'DashboardCtrl',
data: {authorizedRoles: [USER_ROLES.superAdmin, USER_ROLES.admin, USER_ROLES.system, USER_ROLES.user]},
resolve: {nextEvents: function (Session, $injector) {
$http = $injector.get('$http');
return $http.get(actionBaseUrl + '/devices/nextEvents', {
params: {
userId: Session.userId, batch: {rows: 5, page: 1}
},
isArray: true}).then(function success(response) {
return response.data;
});
}
}
})
...
.otherwise({
redirectTo: '/home'
});
}]);