我设置了身份验证,我希望阻止任何路由/状态加载,直到我知道用户有权访问该页面。如果是,则应加载请求的页面,如果没有,则应该进入登录页面。
我的配置功能:
$stateProvider
.state('login', {
url: '/login',
templateUrl : 'login.html',
controller : 'loginController',
data: {
authorizedRoles: [USER_ROLES.guest]
}
})
.state('home', {
url: '/',
templateUrl : 'home.html',
controller : 'homeController',
data: {
authorizedRoles: [USER_ROLES.admin]
}
})
.state('admin', {
url: '/admin',
templateUrl : 'admin.html',
controller : 'adminController',
data: {
authorizedRoles: [USER_ROLES.admin]
}
});
$urlRouterProvider.otherwise('/login');
$locationProvider.html5Mode(true);
我的跑步功能:
$rootScope.$on('$stateChangeStart', function(event, next) {
event.preventDefault();
function checkAuthorization() {
if(!AuthService.isAuthorized(authRole)) {
$state.go('login');
} else {
$state.go(next.name);
}
}
if(AuthService.getRoleId() === undefined) {
// We'll have to send request to server to see if user is logged in
AuthService.checkLogin().then(function(response) {
checkAuthorization();
});
} else {
checkAuthorization();
}
})
如果我将event.preventDefault()
保留在我的运行功能中,则应用程序将停留在始终进入请求状态的循环中。如果我删除event.preventDefault()
语句,那么应用程序将加载视图(在一秒钟内可见),然后才意识到不允许用户查看它(然后转到正确的状态)。
我该如何解决这个问题?
答案 0 :(得分:2)
您应该使用resolve并向服务器发出请求,以查看用户是否已登录解析
https://github.com/angular-ui/ui-router/wiki#resolve
.state('whatever',{
...
promiseObj: function($http){
// $http returns a promise for the url data
return $http({method: 'GET', url: '/someUrl'}).$promise;
},
...
}
OR
如果您在控制器中拨打电话,请在解决状态下进行呼叫,如果您没有登录,您的api应该使用401响应,如果您有拦截服务,则重定向到登录屏幕。
答案 1 :(得分:0)
详细说明如何在此Q & A with working plunker中执行此类解析/等待。
Auth服务的提取版本是:
.factory('userService', function ($timeout, $q) {
var user = undefined;
return {
// async way how to load user from Server API
getAuthObject: function () {
var deferred = $q.defer();
// later we can use this quick way -
// - once user is already loaded
if (user) {
return $q.when(user);
}
// server fake call, in action would be $http
$timeout(function () {
// server returned UN authenticated user
user = {isAuthenticated: false };
// here resolved after 500ms
deferred.resolve(user)
}, 500)
return deferred.promise;
},
// sync, quick way how to check IS authenticated...
isAuthenticated: function () {
return user !== undefined
&& user.isAuthenticated;
}
};
})
最重要的部分是
var user = undefined;
- " global"变量是
isAuthenticated
那应该解决这个问题。查看更多详情here