AngularJS | обрабатывать маршрутизацию до загрузки

Я хочу создать простую проверку проверки подлинности для моих маршрутов внешней службой.

Я определяю требования к доступу к объекту маршрута:

$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, даже если я не аутентифицирован.

Как я могу обработать маршрут до их обработки?

Ответы

Ответ 1

Мое решение сочетало $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) таким образом, что если он не сможет вернуть значение false.

Я также использую $routeChangeStart для обработки событий $route.reload(), поэтому теперь после каждого изменения в моем статусе аутентификации я просто делаю $route.reload():

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

Наконец, я просто убеждаюсь, что эта настраиваемая служба всегда будет работать с помощью простого метода run().

Edit:

Теперь мы используем модуль ngAuth, который мы разработали для решения этой точной проблемы (на основе ответа, который я дал здесь ранее).

Наконец, мы разработали angular -модуль, который решил эту проблему. Этот модуль основан на ответе, который я опубликовал здесь раньше.

В связи с запросами здесь мы опубликовали бета-версию, которая работает сейчас: http://github.com/GoDisco/ngAuth

Не стесняйтесь использовать его.

Ответ 2

Используйте $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;
    }
})

Ответ 3

Пример устранения углов:

.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

Попробуйте использовать свойство resolve маршрута. Он разрешает все функции/зависимости, переданные ему перед загрузкой любого контроллера или шаблона. Покорение зависимости возвращает обещание, пока его не разрешат ничего загружать.

Попробуйте передать свою службу проверки подлинности в разрешении и перенаправить сбой с ошибкой auth.

Пожалуйста, посмотрите → https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw

$stateProvider использует $routeProvider под ним. Эта вики даст вам больше информации. https://github.com/angular-ui/ui-router/wiki#resolve

Ответ 5

Angular -http-auth позволяет обрабатывать очень элегантную авторизацию на уровне HTTP (при выборе шаблона) и запрашивать логин, если это необходимо. Все, что даже без загрузки шаблона (или контроллера), если авторизация отклоняется. Очевидно, лучшее, что я видел до сих пор.

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