Angularjs 如何在解析值之前防止状态更改
我设置了身份验证,以防止加载任何路由/状态,直到我知道用户有权访问页面。如果是,则应加载请求的页面,如果不是,则应转到登录页面 我的配置功能:Angularjs 如何在解析值之前防止状态更改,angularjs,authorization,angular-ui-router,Angularjs,Authorization,Angular Ui Router,我设置了身份验证,以防止加载任何路由/状态,直到我知道用户有权访问页面。如果是,则应加载请求的页面,如果不是,则应转到登录页面 我的配置功能: $stateProvider .state('login', { url: '/login', templateUrl : 'login.html', controller : 'loginController', data: { authorizedRo
$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();
}
})
我的跑步功能:
$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();
}
})
如果我在run函数中保留event.preventDefault()
,那么应用程序将陷入一个始终处于请求状态的循环中。如果我删除event.preventDefault()
语句,那么应用程序将在意识到不应允许用户查看视图(然后进入正确状态)之前加载视图(该视图将显示一秒钟)
如何解决此问题?您应该使用resolve并向服务器发出请求,以查看用户是否已登录resolve 或
如果您在控制器中进行了调用,请在resolve in状态下进行调用,在该状态下,如果用户未登录,api应以401响应,如果您有拦截服务,则重定向到登录屏幕 本文详细解释了如何执行此类解决/等待操作 身份验证服务的提取版本为:
.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=未定义代码>-“全局”变量,该变量为
- 包含用户并可以回答他是否有权限
- 不包含用户(尚未),答案为“未授权”
isAuthenticated
这应该可以解决问题。查看更多详细信息我已经对此进行了研究,这似乎是最好的解决方案,但是,我还没有听说过设置拦截。你能举例说明我如何实现你所解释的吗?@cornflakes24看看这个我在responseError中有一个开关,它检查rejection.status并根据它重定向到的某个位置的状态。400->登录401->登录所有其他错误页。@如果使用令牌身份验证,则返回24。拦截器是一种将令牌添加到服务器的每个请求中的好方法。谢谢!似乎即使设置了resolve,它也会开始从州控制器执行代码。我可以使用拦截器获取它,使其正确重定向到登录页面,但不是在从控制器执行一些我不希望执行的代码之后:/@cornflakes24对您必须添加的服务器进行调用。$promise so state等待调用完成,然后运行控制器代码