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 am currently implementing a simple user authentication and I want the user to only be able to view some states if the user is loggedin and the token is not null. This is because on my ionic app, when i refresh a state, it immediately goes to my default page even though the user has been logged in and the user has a token.

So in my app.js, i did the following to check if the user can go to the state,

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {

$ionicLoading.show({
  template: 'Loading...'
});

if (window.sessionStorage.token) {
  $http.defaults.headers.common.Authorization = window.sessionStorage.token;  
  $rootScope.localTokenKey = window.sessionStorage.token;
  $rootScope.isLoggedin = true;
}
else {
  $rootScope.isLoggedin = false;
}

if(toState.data) {
  if(!$rootScope.isLoggedin){
    $state.transitionTo('login', {}, { reload: true, inherit: true, notify: true})
  }
} else {
  console.log("FAILED")
}

})

$rootScope.$on("$stateChangeSuccess", function(event, toState, toParams, fromState, fromParams){ $ionicLoading.hide(); });

state provider config This is the list of the states.

.config(function($stateProvider, $urlRouterProvider, $httpProvider) {


      $stateProvider
      //$controllerProvider.allowGlobals();

      .state('login', {
        url: "/login",
        templateUrl: "templates/login.html",
        controller: 'AppCtrl'
      })

      .state('app', {
        url: "/app",
        abstract: true,
        templateUrl: "templates/menu.html",
        controller: 'MainCtrl'
      })

      .state('app.dashboard', {
        url: "/dashboard",
        views: {
          'menuContent': {
            templateUrl: "templates/dashboard.html",
          }
        },
        authenticate : true
      })

      .state('app.case_status', {
        url: "/case_status",
        views: {
          'menuContent': {
            templateUrl: "templates/case_listing.html",
            controller: 'ReferralCtrl'
          }
        },
        authenticate : true
      })
      .state('app.case_status_single', {
        url: "/case_details",
        views: {
          'menuContent': {
            templateUrl: "templates/case_details.html",
            controller: 'ReferralCtrl'
          }
        },
        authenticate : true

      })

      .state('app.feedback', {
        url: "/feedback",
        views: {
          'menuContent': {
            templateUrl: "templates/feedback.html"
          }
        },
        authenticate : true

      })

      .state('app.new', {
        url: "/new_referral",
        views: {
          'menuContent': {
            templateUrl: "templates/new_referral.html",
            controller: 'NewCaseCtrl'
          }
        },
        authenticate : true
      })

      .state('app.settings', {
        url: "/settings",
        views: {
          'menuContent': {
            templateUrl: "templates/settings.html"
          }
        },
        authenticate : true
      })

      .state('logout', {
          url: "/logout",
          views: {
            'menuContent' : {
            }
          } 
      });

      // if none of the above states are matched, use this as the fallback
     //$urlRouterProvider.otherwise('/login');
    })

When i run my code, the console.log("login page") is executed more than 1000times before it hits an unidentified error then the login page is shown.

What am i doing wrong and how can i solve this issue. I am using AngularJS.

share|improve this question

Don't bother intercepting and preventing the state change if you don't need to do anything (ie, user is logged in).

Also, I'd change the logic to look for a public flag instead of your authenticate flag and assume all states require authentication. In fact, I'd say the fact that your "login" state evaluates toState.authenticate to false is the root of your problem.

Finally, extra state data should go in the data property.

To summarise

  1. Use a public flag on any state that is publicly available

    .state('login', {
        url: "/login",
        templateUrl: "templates/login.html",
        controller: 'AppCtrl',
        data: {
            public: true
        }
    })
    

    and remove the authenticate properties from the other states.

  2. Check for the public flag or $rootScope.isLoggedIn and go to your login state if both are false

    $rootScope.$on('$stateChangeStart', function(event, toState) {
        $ionicLoading.show({
          template: 'Loading...'
        });
    
        if (!((toState.data && toState.data.public) || $rootScope.isLoggedIn)) {
            console.log("login page")
            event.preventDefault(); 
            $state.transitionTo('login', {}, { reload: true, inherit: true, notify: true});
        }
    })
    
share|improve this answer
    
thanks your solution works as now it doesnt refresh a million times but now after logging in, when i refresh a particular page, it still sends me back to the login page. is there anyway of catching that. i read a few places tht it is not good to use cookies but do i hv to end up using tht so tht once it is logged in if i refresh the page, it has a record tht it is logged in nd doesnt set all d values back to false – Kingsley Simon Sep 17 '15 at 4:34
    
@KingsleySimon You'll need to store the authentication state somewhere (localStorage would be my pick), read from that during your app's startup and assign $rootScope.isLoggedIn appropriately – Phil Sep 17 '15 at 4:37
    
i set the stored the token using sessionStorage but for example upon login, it goes to the dashboard page. if i refresh the dashboard page, it still returns to d login page. i made some edits to my initial code to explain better. – Kingsley Simon Sep 17 '15 at 9:14

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.