根据用户的权限,我在登录后会显示两种默认状态之一(让我们称之为foo
和bar
)。我有一个在$stateChangeStart
上运行的功能,它使用用户的权限将它们重定向到正确的屏幕。
foo
权限 - > mybrokenapp.com/foo/dashboard
bar
权限 - > mybrokenapp.com/bar/dashboard
当用户通过登录页面进入时,这非常有效。但是,如果用户已登录(已设置Cookie)并且只访问根网址(mybrokenapp.com
),则重定向不再有效。
我调试了这一点,以至于99%确定错误是由currentRole
运行时$stateChangeStart
未设置引起的。
路由代码:
$stateProvider
.state('app', {
templateUrl: '/path/app.html',
url : '',
resolve: {
authenticated: ['authService', function(authService){
return authService.authenticationStatus(true);
}]
}
})
.state('app.foo', {
abstract: true,
template: '<ui-view/>',
url: "/foo"
})
.state('app.foo.dashboard', {
templateUrl: '/path/dashboard.foo.html',
url: "/dashboard",
controller: 'DashFoo',
controllerAs: 'dashFoo'
})
.state('app.bar', {
abstract: true,
template: '<ui-view/>',
url: "/bar"
})
.state('app.bar.dashboard', {
templateUrl: '/path/dashboard.bar.html',
url: "/dashboard",
controller: 'DashBar',
controllerAs: 'dashBar'
})
.state('login', {
templateUrl: '/path/login.html',
url: "/login",
controller: 'LoginCtrl'
})
根据权限重定向到正确网址的功能:
.run(function($rootScope, $state, authService, userService){
authService.initialize('/api', true);
$rootScope.$on('$stateChangeStart', function (event, toState) {
if (toState.name === 'app') {
if (userService.getUserRoles().currentRole == 'foo') {
event.preventDefault();
$state.go('app.foo.dashboard');
}
if (userService.getUserRoles().currentRole == 'bar') {
event.preventDefault();
$state.go('app.bar.dashboard');
}
}
});
});
有关如何解决此问题的任何想法,或仍然提供相同功能的替代路线设计,将不胜感激。
答案 0 :(得分:0)
请检查我在这个问题中给出的答案。它提供了替代的,可以说是更好的设计 Angular Authentication and Access control
在答案中,您可以根据需要轻松扩展boolean authenticate
参数。并且仅在$ stateChange事件中调用身份验证服务。
答案 1 :(得分:0)
我自己设法解决了这个问题。在ui-router github pages中找到了这个有趣的讨论。
问题解决了:
使用resolve初始化状态定义:{}可以访问ui-router内部使用的实际解析对象,并允许在$ stateChangeStart中添加解析
代码:
.run(function($rootScope, $state, authService, userService, $timeout){
authService.initialize('/api', true);
$rootScope.$on('$stateChangeStart', function (event, toState) {
if (toState.name === 'app') {
toState.resolve.x = function () {
$timeout(function(){ userService.setUserRoles(authService.user); }, 30).then(function(){
if (userService.getUserRoles().currentRole == 'foo') {
event.preventDefault();
$state.go('app.foo.dashboard');
}
if (userService.getUserRoles().currentRole == 'bar') {
event.preventDefault();
$state.go('app.bar.dashboard');
}
});
};
}
});
});
需要30毫秒的超时才能加载authService
时间。虽然这绝不是理想的,但它确实有效。
对上述代码的任何改进都非常受欢迎。