My solution breaks down in 3 parts: the state of the user is stored in a service, in the run method you watch when the route changes and you check if the user is allowed to access the requested page, in your main controller you watch if the state of the user change.
app.run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) { $rootScope.$on('$routeChangeStart', function (event) { if (!Auth.isLoggedIn()) { console.log('DENY'); event.preventDefault(); $location.path('/login'); } else { console.log('ALLOW'); $location.path('/home'); } }); }]);
You should create a service (I will name it Auth
) which will handle the user object and have a method to know if the user is logged or not.
service:
.factory('Auth', function(){ var user; return{ setUser : function(aUser){ user = aUser; }, isLoggedIn : function(){ return(user)? user : false; } } })
From your app.run
, you should listen the $routeChangeStart
event. When the route will change, it will check if the user is logged (the isLoggedIn
method should handle it). It won’t load the requested route if the user is not logged and it will redirect the user to the right page (in your case login).
The loginController
should be used in your login page to handle login. It should just interract with the Auth
service and set the user as logged or not.
loginController:
.controller('loginCtrl', [ '$scope', 'Auth', function ($scope, Auth) { //submit $scope.login = function () { // Ask to the server, do your job and THEN set the user Auth.setUser(user); //Update the state of the user in the app }; }])
From your main controller, you could listen if the user state change and react with a redirection.
.controller('mainCtrl', ['$scope', 'Auth', '$location', function ($scope, Auth, $location) { $scope.$watch(Auth.isLoggedIn, function (value, oldValue) { if(!value && oldValue) { console.log("Disconnect"); $location.path('/login'); } if(value) { console.log("Connect"); //Do something when the user is connected } }, true);