AngularJS: перейти на страницу входа для аутентификации, сохранить маршрут как параметр GET?

Я немного новичок в Angular. Я пытаюсь написать службу Angular, которая на любой странице будет проверять, вошел ли пользователь в систему, и, если нет, перенаправлять их на страницу входа, передавая их текущий путь в качестве параметра GET.

Я почти там, но это не совсем работает. Проблема, с которой я сталкиваюсь, заключается в следующем: если пользователь переходит на #/articles/my-articles/, он перенаправляется на #/login/?next=%2Farticles%2F:module%2F.

Другими словами, похоже, что Angular передает шаблон маршрута, а не фактический URL.

Это мой код аутентификации:

auth.run(['$rootScope', '$location', '$user', 'TOKEN_AUTH', 'PROJECT_SETTINGS', function ($rootScope, $location, $user, TOKEN_AUTH, PROJECT_SETTINGS) {
    var MODULE_SETTINGS = angular.extend({}, TOKEN_AUTH, PROJECT_SETTINGS.TOKEN_AUTH);
    $rootScope.$on('$routeChangeStart', function (e, next, current) {
        if (next.$$route && !next.$$route.anonymous && !$user.authenticated) {
          var nextParam = next.$$route.originalPath;
          $location.url(MODULE_SETTINGS.LOGIN + '?next=' + nextParam);
        }
    });
}]);

Я могу получить исходный путь хакерским способом, используя current.params.module, но это мне не помогает, потому что кажется, что routeChangeStart запускается несколько раз, а объект current не определен во всех случаях, кроме последнего.

Это мой файл маршрутов:

articles.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when('/articles/:module/', {
        templateUrl: 'views/articles/article_list.html',
        controller: 'ArticlesListCtrl'
    })
    .when('/articles/:module/:id/', {
        templateUrl: 'views/articles/article_detail.html',
        controller: 'ArticlesDetailCtrl'
    });
}]);

Как я могу решить эту проблему?


person Richard    schedule 27.11.2013    source источник
comment
Основная проблема заключается в том, что при первом срабатывании routeChangeStart объект current не определен. Только в третий раз, когда он срабатывает, current.params доступен, и к этому моменту next.$$route.anonymous было установлено значение true, поэтому слишком поздно перенаправлять на правильный URL-адрес.   -  person Richard    schedule 27.11.2013


Ответы (2)


auth.run(['$rootScope', '$location', '$user', 'TOKEN_AUTH', 'PROJECT_SETTINGS', function ($rootScope, $location, $user, TOKEN_AUTH, PROJECT_SETTINGS) {
    var MODULE_SETTINGS = angular.extend({}, TOKEN_AUTH, PROJECT_SETTINGS.TOKEN_AUTH);
    $rootScope.$on('$routeChangeStart', function (e, next, current) {
        if (!$user.authenticated) {
          $location.url(MODULE_SETTINGS.LOGIN + '?next=' + $location.path());
          $location.replace();
        }
    });
}]);

Если вход в систему не является представлением AngularJS, вам может потребоваться указать маршрут otherwise:
(зависит от вашей конфигурации $locationProvider)

$routeProvider.otherwise({
    template: 'Redirecting…',
    controller : 'Redirect'
});

...

articles.controller('Redirect', ['$location', function($location) {
    if (someConditionThatChecksIfUrlIsPartOfApp) {
        location.href = $location.path();
        return;
    } else {
        // Show 404
    }
}]);

Дополнительное примечание: вам не следует читать свойства с префиксом $$, они являются частными переменными AngularJS.
Также обратите внимание: не используйте префиксы $ ($user) в своем собственном коде, это общедоступные свойства, зарезервированные для AngularJS.

person Blaise    schedule 27.11.2013
comment
Мгновенное идеальное исправление, большое спасибо :) Также спасибо за общий совет по Angular, очень признателен! - person Richard; 27.11.2013

Мое решение работает на Angular 1.2.13: preventDefault останавливает угловую маршрутизацию, а $window.location отправляет меня на страницу входа. Это работает над приложением ASP.NET MVC + Angular.

$rootScope.$on("$locationChangeStart", function (event, next, current) {
                    event.preventDefault();
                    $window.location = '/Login';
            }        
    });
person RolandoCC    schedule 04.04.2014