17

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

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

$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 做一些不必要的请求。

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

4

5 回答 5

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;
    }
})
于 2013-09-13T14:28:10.203 回答
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解析给定的 URL 到路由..

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

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

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

最后我只是确保这个自定义服务总是会使用简单的run()方法运行。

编辑:

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

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

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

随意使用它。

于 2013-09-14T19:46:46.813 回答
1

尝试使用resolve路线的属性。它在加载任何控制器或模板之前解析所有传递给它的函数/依赖项。以防依赖项返回一个承诺,直到它的解决没有加载。

如果身份验证失败,请尝试在解析和重定向中传递您的身份验证服务。

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

$ stateProvider 在下面使用$routeProvider。这个wiki会给你更多的见解。https://github.com/angular-ui/ui-router/wiki#resolve

于 2013-09-13T14:26:27.097 回答
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;
            }
        }
于 2014-08-28T20:30:26.870 回答
0

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

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

于 2013-09-13T15:44:24.720 回答