角度 |在加载路由之前处理路由



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

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

$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 执行一些不必要的请求,即使我没有经过身份验证。

在他们处理之前,我该如何处理路线?

使用$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;
    }
})

我的解决方案是将$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();
});

我从angular-route.js复制了parseRoute()来解析要路由的给定 URL。

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

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

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

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

编辑:

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

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

由于这里的请求,我们发布了一个现在可以运行的测试版:http://github.com/GoDisco/ngAuth

随意使用它。

Angularjs resolve example:

.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;
            }
        }

尝试使用路由resolve属性。它会在加载任何控制器或模板之前解析传递给它的所有函数/依赖项。如果依赖项返回承诺,则在解决之前不会加载任何内容。

尝试在解析中传递身份验证服务,并在身份验证失败时重定向。

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

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

Angular-http-auth 允许您在 HTTP 级别(获取模板时)非常优雅地处理授权,并在需要时提示登录。如果授权被拒绝,所有这些甚至无需加载模板(或控制器)。显然是我迄今为止见过的最好的事情。

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

相关内容

  • 没有找到相关文章

最新更新