Bir çözüm, "notAuthorized" olayını yayınlamak ve konumu yeniden değiştirmek için ana kapsamda yakalamaktır. Bunun en iyi çözüm olmadığını düşünüyorum ama benim için çalıştı:
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');
}
}
});
}
]);
ve Ana Denetleyicimde:
$scope.$on('notAuthorized', function(){
$location.path('/forbidden');
});
Not: Açısal sitede bu sorunla ilgili henüz çözülmemiş bazı tartışmalar var:
https://github.com/angular/angular.js/pull/4192
DÜZENLE:
Yorumu yanıtlamak için, LoginService çalışmaları hakkında daha fazla bilgi burada. 3 işlevi içerir:
- login () (ad yanıltıcıdır) (önceden) oturum açmış kullanıcı hakkında bilgi almak için sunucuya bir istekte bulunun. Sunucudaki mevcut kullanıcı durumunu (SpringSecurity çerçevesini kullanarak) dolduran başka bir oturum açma sayfası daha vardır. Web Servislerim gerçek anlamda vatansız değildir, ancak güvenliğimi bu ünlü çerçevenin üstlenmesine izin vermeyi tercih ettim.
- isAuthenticated () sadece istemci Oturumunun verilerle dolu olup olmadığını araştırır, bu da daha önce doğrulandığı anlamına gelir (*)
- isAuthorized () erişim haklarını işledi (bu konu için kapsam dışında).
(*) Rota değiştiğinde Oturumum doldurulur. Oturumu boşken doldurmak için when () yöntemini geçersiz kıldım.
İşte kod:
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) {
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);
};
$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'
});
}]);