Reputation: 2210
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.
Upvotes: 0
Views: 1104
Reputation: 164767
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
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.
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});
}
})
Upvotes: 0