Một giải pháp là phát sự kiện 'notAuthorized' và nắm bắt nó trong phạm vi chính để thay đổi lại vị trí. Tôi nghĩ đó không phải là giải pháp tốt nhất, nhưng nó đã hiệu quả với tôi:
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');
}
}
});
}
]);
và trong Bộ điều khiển chính của tôi:
$scope.$on('notAuthorized', function(){
$location.path('/forbidden');
});
Lưu ý: có một số thảo luận về vấn đề này trên trang web góc cạnh, chưa được giải quyết:
https://github.com/angular/angular.js/pull/4192
BIÊN TẬP:
Để trả lời nhận xét, đây là thông tin thêm về các hoạt động của LoginService. Nó chứa 3 chức năng:
- login () (tên bị nhầm lẫn) thực hiện một yêu cầu tới máy chủ để lấy thông tin về người dùng đã đăng nhập (trước đó). Có một trang đăng nhập khác chỉ điền trạng thái người dùng hiện tại trong máy chủ (sử dụng SpringSecurity framework). Các Dịch vụ Web của tôi không thực sự không có trạng thái, nhưng tôi muốn để khuôn khổ nổi tiếng đó xử lý bảo mật của tôi.
- isAuthenticated () chỉ cần tìm kiếm nếu Phiên khách chứa đầy dữ liệu, có nghĩa là nó đã được xác thực trước đó (*)
- quyền truy cập được xử lý isAuthorized () (ngoài phạm vi của chủ đề này).
(*) Phiên của tôi được điền khi tuyến đường thay đổi. Tôi đã ghi đè phương thức when () để điền phiên khi trống.
Đây là mã:
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'
});
}]);