Join the Stack Overflow Community
Stack Overflow is a community of 6.3 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I'm trying to create a very simple authentication control using ui-router. I do the checking in the backend, though, I want to redirect users if they aren't logged in.

However, when I try to visit /profile, nothing happens. If I console.log() a text like "yes", it's being logged out unlimited amount of time until I get stack size exceeded error. It keeps hitting /authcheck url, I can see that via network tools of Chrome.

If I remove $state.go(toState.name), I see a blank page and console.log() shows that user is signed in (which I am), but then I can't see /profile page, as expected.

What could be the problem here?

/authcheck returns 200 or 403.

my factory

angular.module('site.profile').factory('Profile', ["$http", function($http) {
  return {
    authCheck: function() {
      return $http.get('/authcheck');
    }
  };
}]);

ui-router

angular.module('site.profile.routes')
.run(
  ['$rootScope', 'Profile', '$state', '$stateParams',
    function($rootScope, Profile, $state, $stateParams) {
      $rootScope.$state = $state;
      $rootScope.$stateParams = $stateParams;
      $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
        if (toState.name !== 'auth') {
          event.preventDefault();
          Profile.authCheck().then(function(returned) {
            if (returned.status === 200) {
              console.log("yes!");
              console.log(toState.name);
              //$state.go($state);
            } else {
              $state.go('auth');
            }
          });
        }
      });
    }
  ]
)


.config(
  ['$stateProvider', '$urlRouterProvider', '$locationProvider',
    function($stateProvider, $urlRouterProvider, $locationProvider) {

      $locationProvider.html5Mode({
        enabled: true,
        requireBase: false
      });

      $stateProvider
        .state('profile', {
          url: '/profile',
          views: {
            '': {
              templateUrl: 'views/profile/profile.html'
            },
            'post@profile': {
              templateUrl: 'views/post.html'
            },
            'nav@profile': {
              templateUrl: 'views/shared/nav/nav.html'
            },
            'top@profile': {
              templateUrl: 'views/profile/top.html'
            }
          }
        })
        .state('auth', {
          url: '/signin',
          template: "please sign in"
        });
    }
  ]);
share|improve this question
up vote 1 down vote accepted

You are preventing the default for every state change except auth.

You need a way to store user once they have been authorized so you don't need to make a new request each time and then you can check if that user object exists before preventing the change

I personally prefer using a resolve in a top level parent state so the authorization only needs to be checked once on the parent. Then all child states will be blocked until that parent is resolved

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.