Angular ui-router: how to prevent access to a state

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.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)