AngularJS | 在加载之前处理路由

Alm*_*aku 17 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: '/'
    })
;
Run Code Online (Sandbox Code Playgroud)

然后,我检查我是否在$routeChangeStart活动中获得了许可.

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

实际上,它是有效的 -
如果未经过身份验证的用户将他移动到登录页面,如果他已经过身份验证但路由仅供匿名用户使用,则将其移至另一个页面等.

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

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

cod*_*mer 23

使用$ routeProvider解析

.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;
    }
})
Run Code Online (Sandbox Code Playgroud)

  • 注意:使用angular 1.3,我必须将resolve函数包装在一个对象中,否则它将不会被调用:`resolve:{load:function(){...}}` (4认同)
  • 您是否必须在每条路线上执行此操作,还是将其置于rootScope事件中? (3认同)
  • @AlmogBaku你必须要解决每条路线以使其发挥作用.rootScope事件回调中发生的事情只是一个回调,它无法阻止将要发生的事情.但在解决所有结算之前,路线不会显示.为了使其成为现实,您可以定义一个函数并将相同的函数附加到每个路径结算. (2认同)

Alm*_*aku 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();
});
Run Code Online (Sandbox Code Playgroud)

我复制parseRoute()angular-route.js给定的URL解析路由..

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

我也$routeChangeStart用来处理$route.reload()事件,所以现在在我的身份验证状态中的每次更改之后我都会这样做$route.reload():

$rootScope.$on('$routeChangeStart', function (event, next) {
    Auth.loginCheck(next);
});
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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

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

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

随意使用它.

  • @Jaimin请参阅https://github.com/GoDisco/ngAuth但是要知道 - 它仍处于开发阶段 (2认同)