假设我有4条路线 - 2条要求用户登录,2则不需要。我的app init看起来像:
$routeProvider.when('/open1',{templateUrl:'/open1.html',controller:'Open1'});
$routeProvider.when('/open2',{templateUrl:'/open2.html',controller:'Open2'});
$routeProvider.when('/secure1',{templateUrl:'/secure1.html',controller:'Secure1'});
$routeProvider.when('/secure2',{templateUrl:'/secure2.html',controller:'Secure2'});
路由/open1
和/open2
对所有人开放,而路由/secure1
和/secure2
要求用户登录,如果没有,请采取一些措施,例如重定向到登录或发出警告。我可以使用Auth
服务并致电(例如Auth.isLogin()
)来确定用户的状态。结果将是:
/open1
和/open2
始终转到上面声明的模板和控制器Auth.isLogin()
返回true,/secure1
和/secure2
会转到上面声明的模板和控制器Auth.isLogin()
返回false,/secure1
和/secure2
会采取其他行动,例如$location.path('/login')
我可以将逻辑放在检查的Secure1
和Secure2
控制器中,但这是重复的,混淆了责任,使得它们更难以测试等等。
有没有办法可以使用$routeProvider
来声明,“检查这条路线和这条路线,如果没有,重定向”?我正在考虑以某种方式使用resolve
,但不太确定如何使用它(resolve
上的文档不是很清楚,并且很少有用的示例)。
编辑:
基于以下答案,似乎有三种理念可以做到这一点:
resolve
检查已登录并未通过承诺,然后捕获$routeChangeError
事件以重定向http://www.sitepoint.com/implementing-authentication-angular-applications/ $routeChangeStart
事件检查已登录并重定向http://arthur.gonigberg.com/2013/06/29/angularjs-role-based-auth/ 第二个选项是两位回答者所建议的。
答案 0 :(得分:13)
如上所述,有3种不同的路径(如果你想在html模板中控制它,还可以使用指令)。我最后跟着
https://midgetontoes.com/angularjs-check-user-login/
基本上如下:
$routeProvider.when('/secure', {
templateUrl: '/secure.html',
controller: 'Secure',
resolve:{
loggedIn:onlyLoggedIn
}
});
然后onlyLoggedIn
:
var onlyLoggedIn = function ($location,$q,Auth) {
var deferred = $q.defer();
if (Auth.isLogin()) {
deferred.resolve();
} else {
deferred.reject();
$location.url('/login');
}
return deferred.promise;
};
简单,就像一个魅力。如果我需要一个指令,我会把这件作品提供给服务。
答案 1 :(得分:4)
This blog post使用指令处理AngularJS中的用户身份验证。
$ route服务在路由更改之前发出$ routeChangeStart。
如果您不使用指令,则可以通过调用app.run来捕获该事件(您可以将其放在定义路由[app.config]的代码之后)。例如:
要完全披露我使用ui.router,这是我在我的应用中使用$stateChangeStart的改编代码
var app = angular.module('app');
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/open1',{templateUrl:'/open1.html',controller:'Open1'});
$routeProvider.when('/open2',{templateUrl:'/open2.html',controller:'Open2'});
$routeProvider.when('/secure1',{templateUrl:'/secure1.html',controller:'Secure1'});
$routeProvider.when('/secure2',{templateUrl:'/secure2.html',controller:'Secure2'});
}]);
app.run(['$rootScope', '$location', 'Auth', function($rootScope, $location, Auth) {
$rootScope.$on('$routeChangeStart', function(event, currRoute, prevRoute){
var logged = Auth.isLogin();
//check if the user is going to the login page
// i use ui.route so not exactly sure about this one but you get the picture
var appTo = currRoute.path.indexOf('/secure') !== -1;
if(appTo && !logged) {
event.preventDefault();
$location.path('/login');
}
});
}]);
答案 2 :(得分:3)
我遇到了同样的问题,我这样做了:
var app = angular.module('myModule',["ui-bootstrap"]);
然后在应用程序中监听位置更改(这也将触发页面的输入)
app.run(function ($rootScope, $location, $cookieStore) {
$rootScope.$on("$locationChangeStart", function (event, next, current) {
//Here you can check whatever you want (servercall, cookie...)
});
}
我希望这有帮助!