0

I'd like my app to send non-logged in users to a login page. Based on a popular answer here, the app watches for routeChangeStart, like this:

$rootScope.$on("$routeChangeStart", function(event, next, current) {
    if ($rootScope.currentUser === null) {
        var allowPublic = ["partials/logIn.html", "partials/start.html"];
        var allowed = _.contains(allowPublic, next.templateUrl);
        if (!allowed) {
            $location.path("/logIn").replace();
        }
    }
});

This logic runs correctly, except that changing $location.path doesn't work. The address bar in the browser changes to /logIn, but the view still shows the non-permitted partial. Does anybody have an idea why?

My routes are setup like this:

$routeProvider.when('/start', {templateUrl: 'partials/start.html', controller: 'StartController'});
$routeProvider.when('/logIn', {templateUrl: 'partials/logIn.html', controller: 'LogInController'});
$routeProvider.when('/restricted', {templateUrl: 'partials/restricted.html', controller: 'RestrictedController'});

The start page controller sometimes tries to navigate to the restricted page, like this:

// in StartController
$scope.pressedButton = function() {
    $location.path('/restricted');
    // I'd like to catch this and redirect using the previous logic if user is not logged in
};
user1272965
  • 2,814
  • 8
  • 29
  • 49

1 Answers1

0

In case someone comes across this in the future, here's what I did, though I can't say I fully understand why I had to do it. The fix was to wrap the location change in a timeout.

        if (!allowed) {
            $timeout(function() {
                $location.path("/logIn").replace();
            }, 0);
        }

It think the problem arose because my code was trying to change the location while it's listening for location changes, leading to a regress (which is then halted by the fact that the second call is for a permitted location). By wrapping the path change in $timeout, I guess I'm letting the first location change finish before forcing the redirect.

I'm not 100% sure about this, but I came to the conclusion reading the "Triggering Events Programmatically" section in this angular doc.

This is sensible, I guess, but I wonder why the many route security solutions I read about didn't mention this danger. (e.g. see the massively up-voted answer here).

Community
  • 1
  • 1
user1272965
  • 2,814
  • 8
  • 29
  • 49