AngularJS |在加载之前处理路由

时间:2013-09-13 14:16:42

标签: javascript authentication angularjs angularjs-routing angularjs-authentication

我希望通过外部服务为我的路线创建一个简单的身份验证检查。

我定义了路由对象的访问要求:

$routeProvider
    .when('/', {
        templateUrl: 'src/app/views/index.html',
        controller: 'indexCtrl',
        authenticated: true
    })
    .when('/login', {
        templateUrl: 'src/app/views/login.html',
        controller: 'loginCtrl',
        anonymous:  true
    })
    .otherwise({
        redirectTo: '/'
    })
;

然后,我检查$routeChangeStart事件中是否有权限。

$rootScope.$on('$routeChangeStart', function (event, next) {
    if(next.authenticated && !$myService.isLoggedin())
        $location.path("/login");
    else if(next.anonymous && $myService.isLoggedin())
        $location.path("/secured");
});

实际上,它有效 如果未经过身份验证的用户将其移至登录页面,如果他已通过身份验证,但路由仅供匿名用户使用,则将其移至其他页面等等。

但是 - 在控制器和模板加载后,实际发生了这种重定向! 并且它导致我的控制器对我的REST API做了一些不必要的请求,即使我没有经过身份验证。

如何在处理之前处理路线?

5 个答案:

答案 0 :(得分:23)

使用$routeProvider resolve

.when('/', {
    templateUrl: 'src/app/views/index.html',
    controller: 'indexCtrl',
    resolve: function($q, $location) {
      var deferred = $q.defer(); 
      deferred.resolve();
      if (!isAuthenticated) {
         $location.path('/login');
      }

      return deferred.promise;
    }
})

答案 1 :(得分:16)

我的解决方案是合并$locationChangeStart$routeChangeStart

$rootScope.$on('$locationChangeStart', function (event) {
    //If login data not available, make sure we request for it
    if($facebook.isConnected()==null) {
        $facebook.getLoginStatus();
        event.preventDefault();
        return;
    }

    var next=parseRoute().$$route;
    if(!Auth.loginCheck(next))
        event.preventDefault();
});

我从parseRoute()复制了angular-route.js来解析给定的网址以进行路由..

然后我构建我的登录检查处理程序(Auth.loginCheck),如果失败则返回false。

我还使用$routeChangeStart来处理$route.reload()个事件,所以现在在我的身份验证状态中的每次更改后,我都会$route.reload()

$rootScope.$on('$routeChangeStart', function (event, next) {
    Auth.loginCheck(next);
});

最后,我确保始终使用简单的run()方法运行此自定义服务。

编辑:

我们现在使用ngAuth,我们设计的模块来解决这个问题(基于我之前给出的答案)。

最后,我们开发了一个解决了这个问题的角度模块。这个模块基于我之前发表的答案。

根据此处的要求,我们发布了一个现在可用的测试版:http://github.com/GoDisco/ngAuth

随意使用它。

答案 2 :(得分:1)

尝试使用路线的resolve属性。它解决了在加载任何控制器或模板之前传递给它的所有函数/依赖项。 如果依赖关系返回一个promise,直到它解析为什么都没有加载。

尝试在解析和重定向验证身份验证服务时传递身份验证服务。

请看一下 - > https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw

$ stateProvider 在下方使用 $ routeProvider 。这个维基将为您提供更多见解。 https://github.com/angular-ui/ui-router/wiki#resolve

答案 3 :(得分:1)

Angularjs解析示例:

.when('/profile', {
        templateUrl: 'views/profile.html',
        controller: 'ProfileCtrl',
        resolve: {
            app: function($q, $rootScope, $location) {
                var defer = $q.defer();
                if ($rootScope.currentUser == undefined) {
                    $location.path('/login');
                };
                defer.resolve();
                return defer.promise;
            }
        }

答案 4 :(得分:0)

Angular-http-auth允许您在HTTP级别(获取模板时)处理非常优雅的授权,并在需要时提示登录。如果授权被拒绝,甚至没有加载模板(也不是控制器)。显然,到目前为止我见过的最好的东西。

https://github.com/witoldsz/angular-http-auth