继续之前,angularjs ui路由器授权
我有一个angularjs ui路由器的情况,其中:继续之前,angularjs ui路由器授权,angularjs,angular-ui-router,Angularjs,Angular Ui Router,我有一个angularjs ui路由器的情况,其中: 用户必须在点击任何页面之前获得授权 如果用户已授权且没有路由,请重定向到其主页 如果用户已授权并拥有路由,则重定向到路由 如果用户已授权且没有路线和主页,请导航到默认页面 若用户未经授权且有路由,则重定向至登录页面,并在授权后重定向至该路由 这是一个棘手的情况,我似乎不能正确地处理它。我当前的代码确实有效,但是。。。在导航之前,它必须在一瞬间显示“登录”页面。发生这种情况是因为我必须以某种方式启动$stateChangeStart var
- 用户必须在点击任何页面之前获得授权
- 如果用户已授权且没有路由,请重定向到其主页
- 如果用户已授权并拥有路由,则重定向到路由
- 如果用户已授权且没有路线和主页,请导航到默认页面
- 若用户未经授权且有路由,则重定向至登录页面,并在授权后重定向至该路由
$stateChangeStart
var app = angular.module('myapp', ['ui.router']);
// handle default states based on authentication,
// default properties set in user profile, or
// or just redirect to 'apps' page
var authd = false,
defaultDashboard = undefined,
defaultFn = function($injector){
// required to get location since loaded before app
var $location = $injector.get('$location');
// if the user has a default dashboard, navigate to that
if(defaultDashboard){
$location.path('workspace/' + defaultDashboard);
} else if(authd) {
// if the user is auth'd but doesn't have url
$location.path('home');
} else {
// if we aren't auth'd yet
$location.path('login');
}
};
app.config(function ($urlRouterProvider, $locationProvider, $stateProvider) {
$locationProvider.html5Mode(true);
app.stateProvider = $stateProvider;
$urlRouterProvider.otherwise(function($injector){
defaultFn($injector);
});
});
app.run(function ($rootScope, $q, $location, $state, $stateParams, $injector, security) {
var deregister = $rootScope.$on("$stateChangeStart", function () {
// authorize is a AJAX request to pass session token and return profile for user
security.authorize().success(function(d){
// set some local flags for defaultFn
authd = true;
defaultDashboard = d.defaultDashboard;
// de-register the start event after login to prevent further calls
deregister();
// switch to default view after login
if($location.$$url === "/login" ||
$location.$$url === "/"){
defaultFn($injector);
}
}).error(function(){
$location.path('login');
});
});
});
我用一个接收器来处理401,比如:
var module = angular.module('security.interceptor', []);
// This http interceptor listens for authentication failures
module.factory('securityInterceptor', function($injector, $location) {
return function(promise) {
// Intercept failed requests
return promise.then(null, function(originalResponse) {
if(originalResponse.status === 401) {
$location.path('/login');
}
return promise;
});
};
});
// We have to add the interceptor to the queue as a string because the
// interceptor depends upon service instances that are not available in the config block.
module.config(function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.responseInterceptors.push('securityInterceptor');
});
有人遇到过类似的情况并找到了更好的解决方案吗?这是我提出的解决方案:
app.config(function ($urlRouterProvider, $locationProvider, $stateProvider) {
$locationProvider.html5Mode(true);
// placeholder
$stateProvider.state('welcome', {
url: '/'
});
$urlRouterProvider.otherwise('404');
});
app.run(function ($rootScope, $q, $location, $state, $stateParams, security, $urlRouter) {
var deregister = $rootScope.$on("$stateChangeStart", function (event) {
// stop the change!
event.preventDefault();
security.authorize().success(function(d){
// if we don't have a previous url
if($location.$$url === "/" || $location.$$url === "/login"){
// If user has a preset home
if(d.defaultDashboard){
$location.path('workspace/' + d.defaultDashboard);
} else {
$location.path('welcome');
}
} else {
// if we do, then continue
$urlRouter.sync();
}
}).error(function(){
// redirect to home
$location.path('login');
});
// deregister the listener
deregister();
});
});
基本上,为空路由创建空路由解决了我的问题。有趣。我不确定将重路由放在.run函数中是否是一个很好的解决方案。为什么要先设置$location.path,然后再等待.run启动它?为什么不使用$state.go()。最后,如何以及在何处存储会话数据?本地存储?还有别的吗?@Bonatoc-它是一个服务器请求,它是一个用户配置文件。关于跑步,你能提供更多的细节吗?你有没有把本教程作为你的脚本的基础。是的,我的坏,.run显然是执行身份验证检查的地方,因为它是在.config之后触发的。@bonatocya类似的,我添加了我使用的接收器