我编写了一个应用程序,在处理路由之前,我需要在应用程序运行时检索当前登录的用户信息。我使用ui-router来支持多个/嵌套视图并提供更丰富的有状态路由。
当用户登录时,他们可能会存储一个代表其身份验证令牌的 cookie。我将该令牌包含在对服务的调用中,以检索用户的信息,其中包括他们所属的组。然后在服务中设置生成的身份,在该服务中可以检索并在应用程序的其余部分中使用它。更重要的是,路由器将使用该身份来确保它们已登录并属于适当的组,然后再将它们转换为请求的状态。
我有这样的代码:
app
.config(['$stateProvider', function($stateProvider) {
// two states; one is the protected main content, the other is the sign-in screen
$stateProvider
.state('main', {
url: '/',
data: {
roles: ['Customer', 'Staff', 'Admin']
},
views: {} // omitted
})
.state('account.signin', {
url: '/signin',
views: {} // omitted
});
}])
.run(['$rootScope', '$state', '$http', 'authority', 'principal', function($rootScope, $state, $http, authority, principal) {
$rootScope.$on('$stateChangeStart', function (event, toState) { // listen for when trying to transition states...
var isAuthenticated = principal.isAuthenticated(); // check if the user is logged in
if (!toState.data.roles || toState.data.roles.length == 0) return; // short circuit if the state has no role restrictions
if (!principal.isInAnyRole(toState.data.roles)) { // checks to see what roles the principal is a member of
event.preventDefault(); // role check failed, so...
if (isAuthenticated) $state.go('account.accessdenied'); // tell them they are accessing restricted feature
else $state.go('account.signin'); // or they simply aren't logged in yet
}
});
$http.get('/svc/account/identity') // now, looks up the current principal
.success(function(data) {
authority.authorize(data); // and then stores the principal in the service (which can be injected by requiring "principal" dependency, seen above)
}); // this does its job, but I need it to finish before responding to any routes/states
}]);
如果我登录、导航、注销等,一切都会按预期工作。问题是,如果我在登录时刷新或删除 URL,我会被发送到登录屏幕,因为身份服务调用没有在状态改变之前完成。但是,在该呼叫完成后,如果有链接或其他东西到状态,我可以继续按预期工作main
,所以我快到了。
我知道您可以让状态在转换之前等待解析参数,但我不确定如何继续。