Hello I'm new to angularJS and have been trying to prevent access to certain states based on user critera.
This, from ui-router's FAQ describes exactly what I want to do, but I cant get it to work properly. What do I need to but in the data object exactly to accomplish this?
(I saw someone throwing in "true" on some blog post tutorial and using it like how I have, but that doesnt seem to work because I get an error that says needAdmin is not defined)
Here is my code:
angular.module('courses').config(['$stateProvider',
function($stateProvider) {
// Courses state routing
$stateProvider.
state('listCourses', {
url: '/courses',
templateUrl: 'modules/courses/views/list-courses.client.view.html'
}).
state('createCourse', {
url: '/courses/create',
templateUrl: 'modules/courses/views/create-course.client.view.html',
data: {
needAdmin: true
}
}).
state('viewCourse', {
url: '/courses/:courseId',
templateUrl: 'modules/courses/views/view-course.client.view.html'
}).
state('editCourse', {
url: '/courses/:courseId/edit',
templateUrl: 'modules/courses/views/edit-course.client.view.html',
data: {
needAdmin: true
}
});
}
]);
angular.module('courses').run(['$rootScope', '$state', 'Authentication', function($rootScope, $state, Authentication) {
$rootScope.$on('$stateChangeStart', function(e, to) {
var auth = Authentication;
console.log(auth.user.roles[0]);
if (to.data.needAdmin && auth.user.roles[0] !== 'admin') {
e.preventDefault();
$state.go('/courses');
}
});
}]);
The best way I have found to do this uses resolve:
$stateProvider.
state('createCourse', {
url: '/courses/create',
templateUrl: 'modules/courses/views/create-course.client.view.html',
resolve: {
security: ['$q', function($q){
if(/*user is not admin*/){
return $q.reject("Not Authorized");
}
}]
}
});
This will trigger an error, preventing the user from accessing this state if they are not allowed.
If you need to show an error, or send the user to a different state, handle the $stateChangeError event:
$rootScope.$on('$stateChangeError', function(e, toState, toParams, fromState, fromParams, error){
if(error === "Not Authorized"){
$state.go("notAuthorizedPage");
}
If you want to check for admin access on all states, you could use a decorator to add the resolve to all states. Something like this:
$stateProvider.decorator('data', function(state, parent){
var stateData = parent(state);
var data = stateData.data || {};
state.resolve = state.resolve || {};
if(data.needAdmin){
state.resolve.security = ['$q', function($q){
if(/*user is not admin*/){
return $q.reject("Not Authorized");
}
}];
return stateData;
});
I implemented something like this for my current application. If user is not logged in, we forward the user to a login form. If non-admin user attempts to hit any admin state, we forward to an error page.
If a state has no data
, then to.data
is undefined. Try this:
if (to.data && to.data.needAdmin && auth.user.roles[0] !== 'admin') {
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With