在使用routeProvider在Angular中启动路由之前,如何检查登录或其他状态?

时间:2014-11-18 12:03:45

标签: angularjs angular-routing

假设我有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')

可以将逻辑放在检查的Secure1Secure2控制器中,但这是重复的,混淆了责任,使得它们更难以测试等等。

有没有办法可以使用$routeProvider来声明,“检查这条路线和这条路线,如果没有,重定向”?我正在考虑以某种方式使用resolve,但不太确定如何使用它(resolve上的文档不是很清楚,并且很少有用的示例)。

编辑:

基于以下答案,似乎有三种理念可以做到这一点:

第二个选项是两位回答者所建议的。

3 个答案:

答案 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...)
 });
}

我希望这有帮助!