AngularJS - prevent not authenticated user from accessing given routes
angularjs, javascript, security
Solution
I'd do something like this in the top level controller, which would be the first controller that's called when the page is refreshed (apologize for typos in the js, I'm a coffeescript guy):
var authCheck = function (event, next, current) {
if(isRouteRestricted(next)) {
authService.currentUser().then(null, function() {
$location.path('/login');
});
}
}
authCheck(null, populateNextSomehow).then(function () {
// all of your controller code, probably in a separate function
});
$rootScope.$on("$routeChangeStart", authCheck);
This will ensure that the controller code cannot be called until the authCheck is complete.
Problem
In my app when user is logged in I have `authService` which sets internal flag `isAuthenticated`. Now on every route change I have listener attached to `$routeChangeStart` event which checks `authService.isAuthenticated()`. If no it should redirect to login route. Problem is when user makes page refresh (all the `authService` settings are lost) and it gets back to login again (while still having valid session on server). This is not what I want. What I'd like to do is to "block" route change until I get the info if user is authenticated (either from `authService` which would be immediate, or from server if no info is available in `authService`, e.g. after refresh). I have such function in `authService` ``` // returns promise currentUser: function() { if (authService.isAuthenticated()) { return $q.when(authService.loggedUser); } return $http.get('/session').then(function(response) { authService.loggedUser = response.user; return $q.when(authService.loggedUser); }); } ``` and would like to use it in event listener. ``` $rootScope.$on("$routeChangeStart", function (event, next, current) { if(isRouteRestricted(next)) { authService.currentUser().then(null, function() { $location.path('/login'); }); } }); ``` The thing is that it doesn't work as expected. I still get the target route visible for a very short time, and then user gets redirected. I believe it is due to nature of promises, but how to get rid of this "blink" effect?